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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@sentzunhat/zacatl

v0.0.64

Published

A modular, high-performance TypeScript microservice framework for Node.js, featuring layered architecture, dependency injection, and robust validation for building scalable APIs and distributed systems.

Readme

Zacatl Framework

Package

npm version npm weekly downloads License: Apache 2.0

Quality

CI CVE scan Release Tests: 691 Coverage: 92.10%

Stack

TypeScript Node.js 26+

CI is the orchestrator — CVE scanning, peer-dependency install checks, the full test suite, and an 8-example Docker smoke matrix, gating every merge to main. CVE scan runs that same audit again on its own weekly schedule so its badge stays live independent of CI. Release reflects the actual tag → npm publish → GitHub Release pipeline, only fired by real releases. There's no separate "Publish dry-run" badge: that check only runs as part of CI (gated on a pending version bump), and giving it its own trigger would mean it either fails on ordinary non-release pushes or needs to duplicate that gate — not worth it for one more badge. See docs/guidelines/ci-cd-workflow.md for exactly what runs where and why.

Build consistent TypeScript services without giving up the frameworks you already use.

Zacatl gives TypeScript teams a repeatable application → domain → infrastructure → platform structure, built-in dependency injection, type-safe validation, and structured errors. You keep using Fastify, Express, Mongoose, or Sequelize; Zacatl supplies the boundaries that keep those choices from leaking through the whole application.

It is aimed first at teams building modular APIs and backend services that want consistent project structure, replaceable adapters, and earlier feedback from tests and CI/CD.

Table of Contents

✨ Why Zacatl

Zacatl is useful when a service needs to stay understandable as it grows, or when several services need to follow the same architectural rules without sharing one large application.

  • Keep business logic portable: domain services depend on repository ports, while database and platform adapters remain replaceable.
  • Make boundaries visible: routes, validation, services, repositories, and startup wiring have clear homes and test seams.
  • Catch drift earlier: typed contracts, focused tests, dependency checks, and CI-friendly verification make consistency part of the workflow.

| Capability | Detail | | ---------------------------- | ------------------------------------------------------------------ | | 🏗️ Layered Architecture | Strict Application → Domain → Infrastructure → Platform layers | | 💉 Dependency Injection | Built-in DI container via tsyringe | | ✅ Type-Safe Validation | Zod schema support; Yup and optional validation planned | | 🛡️ Structured Errors | 8 custom error types with correlation IDs | | 🗄️ Pluggable ORM Adapters | Sequelize, Mongoose, built-in SQLite via node:sqlite, or custom | | 🌐 Server Framework Choice | Fastify or Express — same domain logic, swap the adapter | | 🌍 Internationalization | Pluggable i18n with filesystem/memory adapters | | 📝 Production Observability | Structured logging and error tracking | | 🧪 Tested | Vitest suite — counts and coverage in the badges; see Testing |

🧭 See It in a Real Service

The fastify-sqlite-react example is a complete greeting CRUD service, not just a bootstrap snippet:

HTTP request
  → validated route handler
  → GreetingService
  → GreetingRepository port
  → SQLite adapter
  → typed response

It includes create, list, update, and delete flows with validation, domain logic, repository wiring, persistence, and a React frontend. Run it locally with:

cd examples/fastify-sqlite-react
docker compose up -d
curl http://localhost:8081/api/greetings

The same greeting flow is implemented across Fastify/Express, SQLite/PostgreSQL/MongoDB, and React/Svelte in the examples matrix, making the adapter boundaries visible instead of theoretical.

🚀 Quick Start

npm install @sentzunhat/zacatl

Core server dependencies are installed with Zacatl. ORM/database adapters use optional peer dependencies (mongoose, mongodb, sequelize, sqlite3, pg) that you install based on what your service uses. SQL projects that use Zacatl's Sequelize adapter should install sequelize plus the dialect driver, for example pg or sqlite3.

Audit note for 0.0.57+: non-SQL consumers should not install sequelize, and should not inherit Sequelize's nested audit surface through Zacatl core. SQL consumers that explicitly install sequelize own that SQL dependency tree. Apps that only need local SQLite can use Zacatl's node:sqlite path on Node 26 without external sqlite3 or Sequelize.

import Fastify from 'fastify';
import { Service, ServiceType, ServerType, ServerVendor } from '@sentzunhat/zacatl/service';

const fastify = Fastify();

const service = new Service({
  type: ServiceType.SERVER,
  layers: {
    application: { entryPoints: { rest: { hooks: [], routes: [] } } },
    domain: { services: [] },
    infrastructure: { repositories: [] },
  },
  platforms: {
    server: {
      name: 'hello-service',
      server: { type: ServerType.SERVER, vendor: ServerVendor.FASTIFY, instance: fastify },
    },
  },
});

await service.start({ port: 3000 });

See examples/ for eight production-ready starters spanning Express/Fastify × SQLite/PostgreSQL/MongoDB × React/Svelte.

🗄️ ORM Adapters

Zacatl doesn't reimplement your database driver — it registers the real thing (Mongoose, Sequelize, or Node's built-in node:sqlite) on the service's platforms.server.databases list, and gives repositories a consistent shape regardless of which one you picked.

Mongoose (excerpt from examples/fastify-mongodb-react):

import mongoose from 'mongoose';
import { DatabaseVendor } from '@sentzunhat/zacatl/service/platforms/server/database/port';

const serviceConfig = {
  // ...
  platforms: {
    server: {
      // ...
      databases: [
        {
          vendor: DatabaseVendor.MONGOOSE,
          instance: mongoose,
          connection: { url: process.env.MONGO_URI ?? 'mongodb://localhost:27017/myapp' },
          indexes: { bootMode: 'create' }, // 'off' | 'create' | 'sync' — safe by default in prod
        },
      ],
    },
  },
};

node:sqlite — zero extra dependencies, no sequelize or sqlite3 needed on Node 26+:

import { DatabaseVendor } from '@sentzunhat/zacatl/service/platforms/server/database/port';

const databases = [{ vendor: DatabaseVendor.NODE_SQLITE, connection: { url: './data/app.db' } }];

Sequelize (Postgres, MySQL, SQLite via the traditional driver) follows the same databases[] shape with DatabaseVendor.SEQUELIZE — see docs/third-party/README.md for the full adapter matrix, and docs/migration/sequelize-sqlite-to-nodesqlite.md if you're moving a small app off Sequelize SQLite.

🏗️ Architecture

flowchart TB
    subgraph App["Application Layer"]
        direction LR
        A1[HTTP Handlers]
        A2[Validation]
        A3[Routes / Hooks]
    end
    subgraph Domain["Domain Layer"]
        direction LR
        D1[Business Logic]
        D2[Services]
        D3[Ports]
    end
    subgraph Infra["Infrastructure Layer"]
        direction LR
        I1[Repositories]
        I2[Database Adapters]
    end
    subgraph Platform["Platform Layer"]
        direction LR
        P1[DI Container]
        P2[Service Startup]
        P3[Server Vendor: Fastify / Express]
    end

    App --> Domain --> Infra --> Platform

Dependencies flow strictly inward — Application depends on Domain, Domain depends on Infrastructure ports (not concrete adapters), and Platform wires the concrete Fastify/Express/Mongoose/Sequelize instances in at startup. The public API surface is stable; internal modules may change between minor versions.

🎯 Platform Support

| Platform | Status | | ------------- | -------------------- | | Server (HTTP) | Stable | | CLI | Planned (stub only) | | Desktop | Planned (stub only) |

For non-HTTP scripts and workers today, use the standalone DI helpers from @sentzunhat/zacatl/dependency-injection directly.

📸 Examples & Screenshots

Every example implements the same greeting CRUD flow behind a different framework/database/frontend combination, so you can compare them directly. Screenshots (and the walkthrough below) are captured automatically via Playwright against the real, dockerized app — not mockups.

Fastify + MongoDB + React, full create → update → delete cycle:

Fastify + MongoDB + React walkthrough

| Example | Server | Database | Frontend | Preview | | ---------------------------------------------------------------- | ------- | ---------- | -------- | -------------------------------------------------------------------------------- | | fastify-sqlite-react | Fastify | SQLite | React | | | fastify-mongodb-react | Fastify | MongoDB | React | | | fastify-postgres-react | Fastify | PostgreSQL | React | | | fastify-sqlite-svelte | Fastify | SQLite | Svelte | |

The full gallery (all 8 examples × 4 states: initial, after-create, after-update, after-delete) lives in examples/README.md.

Run one locally with Docker

cd examples/fastify-sqlite-react
docker compose up -d
curl http://localhost:8081/api/greetings

Each example builds one Docker image containing both the compiled backend and the compiled frontend static files — there's no separate frontend container to wire up. MongoDB/PostgreSQL examples bring their own database sidecar via docker compose; SQLite examples need nothing extra. Full architecture, port table, and image-pinning guidance: examples/DOCKER.md.

📦 Public API Modules

| Module | Import path | | ----------------------- | -------------------------------------------- | | Service | @sentzunhat/zacatl/service | | Configuration | @sentzunhat/zacatl/configuration | | Dependency Injection | @sentzunhat/zacatl/dependency-injection | | Errors | @sentzunhat/zacatl/error | | Logs | @sentzunhat/zacatl/logs | | Localization | @sentzunhat/zacatl/localization | | Utils | @sentzunhat/zacatl/utils | | Third-party re-exports | @sentzunhat/zacatl/third-party/* |

📖 Documentation

Full docs live in docs/. New contributors start with docs/start-here.md.

| Topic | Link | | ------------------------ | ----------------------------------------------------------------------------------------------------- | | Architecture Overview | docs/guidelines/framework-overview.md | | Service Module | docs/service/README.md | | Dependency Injection | docs/dependency-injection/README.md | | Configuration | docs/configuration/README.md | | Errors | docs/error/README.md | | Logs | docs/logs/README.md | | Localization | docs/localization/README.md | | Third-Party + ORM | docs/third-party/README.md | | ESLint | docs/eslint/README.md | | Utils | docs/utils/README.md | | CI/CD Pipeline | docs/guidelines/ci-cd-workflow.md | | Release Notes | docs/changelog.md | | Migration Guides | docs/migration/ |

🧪 Testing

npm test                 # Run all tests
npm run test:coverage    # Coverage report

691 tests across 83 files, 92.10% line coverage. CI runs the full suite plus type-check, lint, and an 8-example Docker smoke matrix before any release — see docs/guidelines/ci-cd-workflow.md for exactly what gates what.

📋 Requirements

  • Node.js: 26.0.0+
  • npm: 11.0.0+
  • TypeScript: 6.0+

🤝 Contributing

  1. Open an issue describing the change.
  2. Branch off it: git checkout -b issue-<number>/type/description
  3. Add tests, update docs, commit with Conventional Commits.

See CONTRIBUTING.md for the full guide.

📄 License

Apache License 2.0 © 2026 Zacatl Contributors

Zacatl is permissively licensed. Please don't use it to harm people.

🤖 Acknowledgments

This framework was built with assistance from AI coding models and agents — including Claude (Anthropic), OpenAI models, GitHub Copilot, and open-source tooling like Cursor and Continue — alongside plenty of human review and decision-making. Zacatl's own design leans into that collaboration: its docs and structure are intentionally written to be navigable by both people and AI agents. Thank you to the teams building these tools.