DEV Community

DevLog 20250711: __init__.py - Package Initialization Across Languages

Revision: 01
Last Update: 2025-07-11

Python: __init__.py

In Python, any folder with an __init__.py file is treated as a package. Beyond merely signaling "this is a package," the body of __init__.py is executed once on the first import of that package:

# mypkg/__init__.py
print("Initializing mypkg…")

from .submodule import foo
foo()
Enter fullscreen mode Exit fullscreen mode
  • Package marker: without it, legacy Python (pre-3.3) wouldn't recognize the folder as importable.
  • Init code: import-time logic, re-exports (via __all__), lazy-loading, package-level constants, or registration hooks.

JavaScript / Node.js: index.js (or main entry)

A folder containing an index.js becomes the "default" module when you require('./dir') or import … from './dir'. Any top-level code in index.js runs on first load:

// mylib/index.js
console.log('Bootstrapping mylib…');
module.exports = {
  foo: require('./foo')
};
Enter fullscreen mode Exit fullscreen mode
  • Entrypoint marker: Node looks for index.js (or whatever "main" says in package.json).
  • Init code: startup logic, polyfills, shared configuration, or wiring of sub-modules.

Go: func init()

Every Go file may define one or more init() functions. They run once per package, before main() or any other package-scope references:

// pkg/foo/foo.go
package foo

import "fmt"

func init() {
    fmt.Println("Initializing package foo")
}

func Foo() { /* … */ }
Enter fullscreen mode Exit fullscreen mode
  • Package discovery: any folder under $GOPATH (or a module) is a package if it contains Go files all declaring the same package name.
  • Init hooks: multiple init() funcs across files get sequenced by the compiler; use sparingly for registration or side-effects.

Java / JVM languages: static initializers

Java packages are a purely naming convention - no file marks a folder as a package. To run code when classes load, you use static initializers in classes:

package com.example.mylib;

public class Bootstrap {
    static {
        System.out.println("Loading com.example.mylib");
        Config.registerAll();
    }
}
Enter fullscreen mode Exit fullscreen mode
  • Package marker: the package declaration in each .java file plus folder layout.
  • Init code: any class with a static block (or a static field initializer) will execute when that class is first loaded by the JVM. You can force it by referencing the class in your app's entry point.

C# / .NET: static constructors

Like Java, namespaces in C# are declared in each file - folders are only convention. To perform per‐assembly or per‐class initialization:

namespace MyCompany.MyLibrary
{
    public static class Bootstrap
    {
        static Bootstrap()
        {
            Console.WriteLine("MyLibrary initializing");
            Registry.Setup();
        }
    }
}
Enter fullscreen mode Exit fullscreen mode
  • Namespace marker: the namespace keyword in code; folder structure optional.
  • Init code: static constructors (static ClassName()) run once before any member of that type is accessed. For assembly-level hooks, you can place [ModuleInitializer] in .NET 5+.

Ruby (Gems): library root file

Ruby gems almost always have a single "root" file under lib/ named after the gem:

# lib/mygem.rb
puts "Initializing MyGem"
require_relative "mygem/version"
require_relative "mygem/core"
Enter fullscreen mode Exit fullscreen mode
  • Package marker: the gemspec tells RubyGems that lib/mygem.rb is the entrypoint.
  • Init code: top-level code in that file runs on the first require 'mygem', used to set up autoloads, mixins, or configuration defaults.

PHP (Composer): bootstrap files

PHP's PSR-4 autoloader maps namespaces to directories, but you often supply a manual bootstrap:

<?php
// src/bootstrap.php
echo "Bootstrapping App…\n";
spl_autoload_register();
define('APP_STARTED', true);
Enter fullscreen mode Exit fullscreen mode
  • Package marker: composer.json's "autoload" section.
  • Init code: any PHP file you include - often named bootstrap.php or init.php - and run before handling a request or CLI command.

Summary of Init-Code Patterns

Language Package Marker Init Hook Mechanism
Python __init__.py Top-level code in __init__.py
Node.js index.js / "main" Top-level code in entry file
Go any folder of Go files func init()
Java package … + folders static { … } blocks
C#/.NET namespace … static ClassName() constructor or [ModuleInitializer]
Ruby gemspec → lib/gem.rb Top-level code in gem root file
PHP composer.json autoload Included bootstrap file

In practice, most ecosystems decouple "marking" a module from "running init code," using either:

  1. A special filename (like Python's __init__.py or Node's index.js), or
  2. Language hooks (Go's init() or JVM/C# static initializers), or
  3. Build-time metadata (Composer's JSON, Ruby's gemspec) combined with an explicit bootstrap include.

References

Top comments (0)