ZetCode

Tcl package Command

last modified October 20, 2026

The Tcl package command provides a mechanism for loading and managing extensions and libraries. It's essential for modular Tcl programming. The command helps organize code into reusable components.

Basic Definition

The package command manages Tcl packages, which are collections of code that can be loaded on demand. Packages help organize large applications.

Key subcommands include require, provide, ifneeded, present and versions. Packages are identified by name and version numbers. package require name ?requirement ...? loads a package and returns the version that was loaded.

Basic Package Require

This shows the simplest usage of package require to load a package.

basic_require.tcl
package require Tk
puts "Tk version: [package present Tk]"

This loads the Tk package and prints its version. The package present command checks if a package is loaded and returns its version; it raises an error if the package has not been loaded. Loading Tk creates the main window, so the script keeps running until that window is closed (on a machine without a display, package require Tk fails).

Package Provide

This demonstrates how to create and provide your own package in Tcl.

mypackage.tcl
package provide mypackage 1.0

proc greet {name} {
    return "Hello, $name!"
}
use_mypackage.tcl
package require mypackage 1.0
puts [greet "World"]

The first file defines a package with version 1.0 and provides a simple proc. The second file requires and uses the package. For package require to find it, the directory holding the first file needs a pkgIndex.tcl file (see below) and must be listed in auto_path or TCLLIBPATH. Without it, the second file fails with "can't find package mypackage 1.0", which is what happens when the two files are simply run one after the other.

Package Version Requirements

You can specify version requirements when requiring packages.

version_require.tcl
package require Tcl 8.6
package require Tk 8.6
puts "Running Tcl [info patchlevel] with Tk [package present Tk]"

This ensures specific minimum versions of Tcl and Tk are loaded. The script will fail if these versions aren't available. A requirement of 8.6 accepts any 8.x version from 8.6 upwards, but not 9.0, because a new major version may be incompatible. Version numbers are dot-separated integers (for example 8.6.12); two parts are common but not required. As in the first example, loading Tk opens a window, so the script keeps running.

Package ifneeded

The package ifneeded command registers how to load a package.

register_package.tcl
package ifneeded mylib 2.0 {
    source [file join $dir mylib.tcl]
}
use_registered.tcl
package require mylib 2.0

The first script registers how to load mylib version 2.0 when requested: the script is stored and evaluated only when the package is required. The variable dir is set by Tcl to the directory of the pkgIndex.tcl file that is being sourced. The second script requires the package, which triggers the loading script. This is typically used in pkgIndex.tcl files. Run as two separate programs, the second one fails with "can't find package mylib 2.0", because the registration is lost when the first interpreter exits.

Package Namespace

Packages often use namespaces to avoid naming conflicts.

namespaced_package.tcl
package provide myns 1.0

namespace eval ::myns {
    variable counter 0
    
    proc increment {} {
        variable counter
        return [incr counter]
    }
}
use_namespaced.tcl
package require myns 1.0
puts [::myns::increment]
puts [::myns::increment]

This creates a package with its own namespace. The counter variable lives in the namespace, so it does not clash with global names, although it can still be reached as ::myns::counter. The package provides the increment procedure. As in the earlier two-file example, loading it with package require needs an index file for the directory.

Package Versions

You can query the known versions of a package after it has been loaded.

package_versions.tcl
package require http
puts "Loaded http version: [package present http]"
puts "Known http versions: [package versions http]"
set latest [lindex [lsort -dictionary -decreasing [package versions http]] 0]
puts "Latest known version: $latest"

This loads the http package, prints the loaded version, and lists all known versions. The package versions command returns the versions of a package that Tcl knows about; a package that has not been loaded or found yet may report none. The versions are sorted with -dictionary so that they compare as version numbers.

Best Practices

This tutorial covered the Tcl package command with practical examples showing its usage in different scenarios.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Tcl Tutorials.