npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@marcus-dutton/atlas

v2.0.15

Published

Atlas is a small, pragmatic dependency-injection framework for Node.js + TypeScript with first-class support for AOT provider emission and a generator (`ad`) that scaffolds Express apps wired to the DI system.

Readme

Atlas — TypeScript Dependency Injection Framework

Atlas is a small, pragmatic dependency-injection framework for Node.js + TypeScript with first-class support for AOT provider emission and a generator (ad) that scaffolds Express apps wired to the DI system.

This README covers the high-level concepts, a quick start, AOT usage and publishing notes.

Features

  • Lightweight DI Container (async resolution)
  • Provider helpers (Express, Socket.IO, Mongoose placeholders)
  • Lifetimes and lifecycle hooks (onInit / onDestroy)
  • App generator (ad) to scaffold apps (interactive or --yes)
  • AOT emitter + runtime hydrator: emit provider manifest at build-time and hydrate at runtime with no discovery

Quick start (developer)

  1. Install dependencies

    npm install
  2. Build the project

    npm run build
    # or build + AOT emit
    npm run emit:aot
  3. Run the CLI (local dev)

    npm run dev
    # or invoke the compiled CLI after build
    node dist/cli/index.js
  4. Generate a new app

    The CLI includes a generator ad new <name> that scaffolds an Express application wired into Atlas providers. Use interactive prompts or pass --yes to accept defaults.

Using the Container (code snippets)

The core Container supports synchronous and asynchronous resolution. Example:

import { Container } from './src/di/container';

const container = new Container();

// register a simple value provider
container.register({ provide: 'CONFIG', useValue: { port: 3000 } });

// register a factory provider
container.register({ provide: 'LOGGER', useFactory: () => console, deps: [] });

// resolve asynchronously
const logger = await container.resolveAsync('LOGGER');
logger.log('Hello from Atlas');

Provider helper examples are exported from src/providers (e.g. provideExpress, provideMongoose, provideSocketIo, provideAppInitializer). Generated apps use these helpers.

App bootstrap

Use bootstrapApp(AppConfig) to prepare a Container from an application config class (this will attempt AOT hydration first, then register any providers declared in the AppConfig):

import { bootstrapApp } from './src/run/bootstrap';
import { AppConfig } from './app.config';

const { container } = await bootstrapApp(AppConfig);
// container is ready; call your Application.start(container) or other explicit startup as desired

Important: bootstrapApp executes APP_INITIALIZER providers so initialization code (DB registration, model registration) runs with DI available.

AOT emitter & runtime hydration

To avoid runtime discovery in production, Atlas supports an AOT emitter that scans your TypeScript sources for AppConfig providers and emits a manifest and small JS registration modules into dist/aot.

Workflow (recommended for production builds):

  1. Run tsc to compile sources to dist.
  2. Run the emitter: node dist/aot/emitter.js (or npm run emit:aot). This creates:
    • dist/aot/providers-manifest.json — provider metadata
    • dist/aot/providers.aot.js — inlined providers when possible
    • dist/aot/providers.js — runtime provider invocation fallback
    • dist/aot/models.js — small models shim (if models discovered)
  3. At runtime bootstrapApp calls hydrateContainerFromAOT(container) which prefers providers.aot.js, falls back to providers.js, and finally parses the manifest to require modules and call factories.

Model registration

  • Use @Model() decorator to mark classes you want the emitter to pick up. If your model exports a static registerModel(conn, container) method the consumer will call it when a MONGOOSE_CONNECTION is available.

Generator (ad)

The CLI ships a generator that scaffolds an Express application pre-wired to Atlas providers. The generator supports interactive (Y/n) prompts for optional features (Socket.IO, Mongoose) and a --yes non-interactive mode.

Templates are located under src/templates (with runtime fallback templates/ used by the compiled dist generator).

Generator usage and flags

The generator command follows the pattern ad new <name> (the CLI binary is ad when installed globally from this package). Key flags:

  • --yes : non-interactive mode; accepts default options and auto-installs dependencies.
  • --no-install : do not run package-manager installs after scaffolding (useful in CI or when you want to manage installs yourself).
  • --no-git : skip git initialization and initial commit.
  • --github : (future) attempt to create a GitHub repo and push the initial commit (not enabled by default).
  • --branch <name> : set the initial branch name for git init (default: main).

Examples:

# interactive (prompts for Socket.IO / Mongoose)
ad new my-app

# non-interactive and install dependencies
ad new my-app --yes

# scaffold without running installs
ad new my-app --yes --no-install

# scaffold without git initialization
ad new my-app --yes --no-git

Notes on installs

  • The generator writes a minimal package.json into the generated project and then runs a package-manager install in that project folder (so dependencies land inside the new project, not the CLI's CWD).
  • The generator detects available package managers by probing pnpm, yarn, and npm (in that order) and runs installs with the detected tool. You can opt out with --no-install.
  • To ensure installs work correctly when the CLI is globally installed (Windows in particular), the generator runs install commands via the system shell so wrapper executables like npm.cmd / pnpm.cmd are resolved.

Troubleshooting

  • If installs fail with spawn ENOENT it usually means the chosen package manager isn't on PATH in your environment. Install Node.js and the package manager you prefer (npm is included with Node.js). Example on Windows: install Node.js from https://nodejs.org/.
  • If git commit fails during initialization, you may need to set user.name and user.email in your git config: git config --global user.name "Your Name" and git config --global user.email "[email protected]".

Tests

There are integration tests for the AOT emitter/consumer under tests/. Run the AOT integration test with:

npm run test:aot

Publishing to npm

The package includes these helpers in package.json:

  • build — runs TypeScript compiler
  • emit:aot — run the emitter against the compiled dist
  • prepublishOnly — configured to run npm run build && node dist/aot/emitter.js before publish

Publishing steps (local interactive):

  1. Login to npm (interactive):

    npm adduser
    # or
    npm login
  2. Verify login:

    npm whoami
  3. Publish (the prepublishOnly hook will build and emit AOT automatically):

    npm publish --access public

CI / token-based publishing

  • For CI, store an npm token in secrets and use npm ci + npm publish --access public with the token configured (e.g., echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc). I can scaffold a GitHub Actions workflow if you'd like.

Contributing & development

  • Run tests and lints as you edit.
  • Emit AOT files again when you change providers or app.config templates: npm run emit:aot.

Using the Config Loader Utility

Atlas provides a utility to load and cache JSON config files with full TypeScript type safety. You can use this utility anywhere in your app:

import { loadConfig } from '@marcus-dutton/atlas';

// Define your config interface
interface MyConfig {
   port: number;
   dbUri: string;
}

// Load and type your config
const config = await loadConfig<MyConfig>('config.json');
console.log(config.port, config.dbUri);

If you do not specify a type, the return type will be any and you will not get IntelliSense or type checking for config properties.

The loader will search for the config file in the current directory, a config/ subdirectory, or the parent directory.


Conventions and recommended patterns

  • App authors should export an AppConfig decorated object/class (the generator creates app.config.ts examples). The emitter looks for @AppConfig({ providers: [...] }) usages.
  • Export models with @Model() and include a static registerModel(conn, container) method for deterministic AOT model registration.

License

Specify your license here (add a LICENSE file). If you plan to publish on npm, ensure your package has the proper license metadata.


If you'd like, I can:

  • Add an example Application + Model demonstrating registerModel for Mongoose.
  • Add a GitHub Actions workflow to run build + emit + publish using an npm token in secrets.
  • Flesh out API docs for Container and provider helpers as separate markdown files.

Which of these should I do next?

Atlas DI - backend DI framework inspired by Angular

This repository contains an initial scaffold for a TypeScript-based dependency injection framework for backend servers (Express, Fastify etc.) inspired by Angular's AOT/JIT style and provider system.

What is included:

  • Core DI primitives (Container, Injectable, Inject decorators)
  • CLI scaffold (generate app, service, controller, gateway, model templates)
  • Provider helpers (stubs for Mongoose, Socket.IO, Express)

Run in dev:

# install deps
npm install

# run CLI in dev using ts-node
npm run dev -- generate app my-app

Example providers usage in app.config.ts:

import { AppConfig } from '../../src/di/decorators';
import { provideMongoose, provideSocketIo } from '../../src/providers';

@AppConfig({
	providers: [
		provideMongoose('mongodb://localhost:27017/mydb'),
		provideSocketIo()
	]
})
export class MyAppConfig {}

CLI examples:

# generate an app scaffold
npm run dev -- generate app demo-app

# generate a service in current workspace
npm run dev -- generate service User