Skip to content

Packages#

Packages in Jac are directories containing .jac or .py files.

Prefer Absolute Imports

Use absolute imports like import from mypackage.module { X } for clarity and maintainability.


Simple Package (No __init__.jac Required)#

Import directly from a package directory. The __init__.jac file is optional.

package_no_init/

package_no_init/main.jac

View on GitHub

package_no_init/mylib/math_utils.jac

View on GitHub

package_no_init/mylib/string_utils.jac

View on GitHub
package_no_init/
├── main.jac
└── mylib/              # No __init__.jac needed!
    ├── math_utils.jac
    └── string_utils.jac
Output

```

add(3, 5): 8 multiply(4, 6): 24 greet('World'): Hello, World! ```


Package with Re-exports#

Use __init__.jac when you want to create a simplified public API.

package_basic/

package_basic/main.jac

View on GitHub

package_basic/mypackage/__init__.jac

View on GitHub

package_basic/mypackage/helper.jac

View on GitHub
package_basic/
├── main.jac
└── mypackage/
    ├── __init__.jac    # Re-exports from helper.jac
    └── helper.jac
Output

```

Package from-import - HELPER_VALUE: Helper value from package Package from-import - helper_func(): Helper function result ```


Nested Package Imports#

Access deeply nested packages using dot notation.

nested_packages/

nested_packages/main.jac

View on GitHub

nested_packages/app/__init__.jac

View on GitHub

nested_packages/app/constants.jac

View on GitHub

nested_packages/app/models/user.jac

View on GitHub

nested_packages/app/services/user_service.jac

View on GitHub
nested_packages/
├── main.jac
└── app/
    ├── __init__.jac
    ├── constants.jac
    ├── models/
    │   ├── __init__.jac
    │   └── user.jac
    └── services/
        ├── __init__.jac
        └── user_service.jac
Output

```

Nested deep - APP_NAME: MyApp Nested deep - get_version(): 1.0.0 Nested deep - create_user('Alice'): User(Alice) from MyApp ```


Re-exports with __init__.jac#

While optional, __init__.jac can be used to create a clean public API by re-exporting symbols.

init_reexport/

init_reexport/main.jac

View on GitHub

init_reexport/mathlib/__init__.jac

View on GitHub

init_reexport/mathlib/operations.jac

View on GitHub

init_reexport/mathlib/constants.jac

View on GitHub

init_reexport/mathlib/calculator.jac

View on GitHub
init_reexport/
├── main.jac
└── mathlib/
    ├── __init__.jac      # Re-exports from submodules
    ├── calculator.jac
    ├── constants.jac
    └── operations.jac
Output

```

Init reexport - add(5, 3): 8 Init reexport - subtract(10, 4): 6 Init reexport - multiply(6, 7): 42 Init reexport - divide(20, 4): 5.0 Init reexport - PI: 3.14159 Init reexport - E: 2.71828 Init reexport - Calculator.compute(10, 2, 'add'): 12 ```

When to use __init__.jac

Use __init__.jac when you want to:

  • Create a simplified public API
  • Hide internal module structure
  • Add package-level constants or initialization

Sibling Subpackage Imports#

Import between sibling subpackages using absolute paths.

sibling_subpackage/

sibling_subpackage/main.jac

View on GitHub

sibling_subpackage/top/sub_a/a_module.jac

View on GitHub

sibling_subpackage/top/sub_b/b_module.jac

View on GitHub
sibling_subpackage/
├── main.jac
└── top/
    ├── __init__.jac
    ├── sub_a/
    │   ├── __init__.jac
    │   └── a_module.jac
    └── sub_b/
        ├── __init__.jac
        └── b_module.jac    # Can import from sub_a
Output

```

Sibling subpkg - A_VALUE: A module value Sibling subpkg - a_func(): A function Sibling subpkg - B_VALUE: B uses A module value Sibling subpkg - b_func(): B calls: A function ```


Key Takeaways#

Concept Description
Packages Directories with .jac or .py files
__init__.jac Optional, useful for re-exports
Absolute imports import from pkg.subpkg.module { X }
Nested access Use dot notation for deep packages

Best Practice

Use absolute imports with full package paths: import from app.models.user { User }. This is explicit and avoids ambiguity.