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

xpressify

v2.2.2

Published

Modern Express CLI — scaffolding and code generation for TypeScript, ESM and Zod-powered Express applications

Downloads

774

Readme

 __   __                        _  __
 \ \ / /                       (_)/ _|
  \ V / _ __  _ __ ___  ___ ___ _| |_ _   _
   > < | '_ \| '__/ _ \/ __/ __| |  _| | | |
  / . \| |_) | | |  __/\__ \__ \ | | | |_| |
 /_/ \_\ .__/|_|  \___||___/___/_|_|  \__, |
       | |                             __/ |
       |_|                            |___/

Modern Express CLI — TypeScript · ESM · Zod

npm version npm downloads Node TypeScript License


What is Xpressify?

Xpressify is a CLI that removes the repetitive setup work of a new Express backend. Run one command and get a production-ready TypeScript + ESM project with structure, security middleware, and tooling already wired.

It also helps after project creation: use generators to add routes, middleware, and TypeScript constructs with consistent architecture and naming — just like Angular CLI does for frontend projects.


Quick Start

# Install globally
npm install -g xpressify

# Create a new project (interactive)
xpressify new my-api

# Or scaffold non-interactively (CI-friendly)
xpressify new my-api --yes --features eslint,prettier,zod

# Start coding
cd my-api
npm run dev

Command Reference

| Command | Description | |---|---| | xpressify new [name] | Scaffold a new Express + TypeScript project | | xpressify generate <type> <component-name> | Generate a component inside an existing project | | xpressify g <type> <component-name> | Alias for generate | | xpressify --help | Show help | | xpressify --version | Show installed version |

The binary is also available as short aliases x and xpressify-clix g route users is equivalent to xpressify generate route users.


new — Create a project

Interactive mode

xpressify new my-api

The command launches an interactive prompt where you pick your package manager, quality tooling, and optional libraries. When done, you get:

my-api/
├── src/
│   ├── app.ts            ← Express app with cors, helmet, rate-limit
│   ├── server.ts         ← Entry point with dotenv
│   ├── routes/
│   ├── controllers/
│   ├── services/
│   ├── middlewares/
│   └── utils/
├── .env.example
├── .gitignore
├── tsconfig.json         ← NodeNext module + moduleResolution
└── package.json          ← "type": "module"

Non-interactive mode

Pass --yes (or any configuration flag) to skip the prompts. This is what you want in CI pipelines, Docker images, and one-shot scaffolding scripts:

# Defaults (npm, no optional features, install deps)
xpressify new my-api --yes

# Pick features and package manager
xpressify new my-api --yes \
  --features eslint,prettier,zod \
  --package-manager pnpm

# Logger feature + specific library
xpressify new my-api --yes \
  --features logger,jwt \
  --logger winston

# Testing framework (vitest or jest)
xpressify new my-api --yes \
  --features testing \
  --testing-library jest

# Docker-ready project
xpressify new my-api --yes \
  --features docker,eslint,prettier

# Scaffold only, skip dependency install
xpressify new my-api --yes --no-install

Flags for new:

| Flag | Description | Default | |---|---|---| | -y, --yes | Skip all prompts | — | | --package-manager <pm> | npm, pnpm, or yarn | npm | | --features <list> | Comma-separated feature list (see below) | `` (none) | | --logger <library> | pino or winston (only with logger feature) | pino | | --testing-library <library> | vitest or jest (only with testing feature) | vitest | | --no-install | Skip dependency installation | install |

What you can select

Code quality tools

| Option | What it does | |---|---| | eslint | Static analysis with TypeScript rules | | prettier | Opinionated code formatting | | husky | Git hooks — auto-adds ESLint + Prettier | | github-actions | CI pipeline for Node 22 / 24 |

Project features

| Option | What it does | |---|---| | zod | Runtime schema validation | | logger | Structured logging — choose pino or winston | | jwt | Adds jsonwebtoken + bcryptjs to deps | | docker | Adds multi-stage Dockerfile, .dockerignore, and docker-compose.yml | | testing | Adds a test framework — choose vitest or jest with sample test |


generate — Add components

Run from anywhere inside your project. Xpressify walks up the directory tree to find package.json and treats that as the project root. Every generator writes files relative to that root — the result does not depend on the directory you ran the command from.

# Route — creates router + controller + service (3 files)
xpressify g route users
xpressify g route user-profile

# Middleware — creates typed Express middleware
xpressify g middleware auth
xpressify g middleware request-logger

# TypeScript constructs — defaults to src/classes, src/interfaces, src/enums
xpressify g class User
xpressify g interface Product
xpressify g enum Status

# Same, with an explicit path (path notation is supported by every generator)
xpressify g class src/models/User
xpressify g interface src/types/Product
xpressify g enum src/domain/Status

# DTO — Zod-aware if zod is in the target project, plain interface otherwise
xpressify g dto CreateUser
xpressify g dto src/dtos/CreateOrder

# Test — picks Vitest or Jest by inspecting the target's devDependencies
xpressify g test users

# Util — defaults to src/utils/ with a .util.ts suffix
xpressify g util format-date
xpressify g util src/modules/auth/token-helpers

Generator types

| Type | Output | |---|---| | route | src/routes/<name>.router.ts + src/controllers/<name>.controller.ts + src/services/<name>.service.ts | | middleware | src/middlewares/<name>.middleware.ts | | class | src/classes/<name>.class.ts (or <path>/<name>.class.ts) | | interface | src/interfaces/<name>.interface.ts (or <path>/<name>.interface.ts) | | enum | src/enums/<name>.enum.ts (or <path>/<name>.enum.ts) | | dto | src/dtos/<name>.dto.ts (or <path>/<name>.dto.ts) — uses Zod schema + z.infer when zod is present, otherwise emits a plain interface | | test | src/__tests__/<name>.test.ts (or <path>/<name>.test.ts) — Vitest or Jest template chosen by detecting the framework in package.json; fails with a hint if neither is installed | | util | src/utils/<name>.util.ts (or <path>/<name>.util.ts) |

Generated files use ESM-compatible .js extensions in relative imports, matching the NodeNext module resolution used in the scaffolded tsconfig.json.


Programmatic API

Xpressify also works as a library. Types, Zod schemas, naming utilities, and error classes are all exported from the main entry point:

import type {
  NewProjectOptions,
  Feature,
  LoggerLibrary,
  TestingLibrary,
  GenerateOptions,
} from 'xpressify';
import {
  NewProjectOptionsSchema,
  TestingLibrarySchema,
  resolveNames,
  XpressifyError,
} from 'xpressify';

// Validate options programmatically
const options = NewProjectOptionsSchema.parse({
  name: 'my-api',
  targetDir: '/projects/my-api',
  packageManager: 'pnpm',
  features: ['eslint', 'prettier', 'zod', 'testing'],
  loggerLibrary: null,
  testingLibrary: 'vitest',
  installDependencies: true,
});

// Use the naming utilities
const names = resolveNames('user-profile');
// { kebab: 'user-profile', pascal: 'UserProfile', camel: 'userProfile', ... }

// Parse a testing library value directly
const lib = TestingLibrarySchema.parse('jest'); // 'jest'

What You Get by Default

Every generated project ships with practical, production-oriented defaults: Express with cors, helmet, and express-rate-limit pre-wired; a /health endpoint out of the box; ESM output via "type": "module" in package.json and NodeNext in tsconfig.json; TypeScript strict mode targeting ES2022; tsx + nodemon for a fast local dev loop with no build step; and dotenv for environment variables. A README.md and .nvmrc are scaffolded so the project is ready to open, run, and share without further setup.

Relative imports in the scaffold use .js extensions (import app from './app.js'), which is what Node requires at runtime for ESM and what tsc preserves under NodeNext module resolution.


Requirements

Node.js >= 22.0.0 (Node 20 reached end-of-life on 2026-04-30).

node --version

Troubleshooting

Invalid CLI input (bad project name, unknown --package-manager, illegal characters in a component name) produces a single, readable error message and exits with code 1. If you need the full stack trace to debug an unexpected failure, set XPRESSIFY_DEBUG=1:

XPRESSIFY_DEBUG=1 xpressify new my-api --yes

If generate fails with "Not inside a Node.js project", make sure you're running the command from somewhere inside a directory tree that contains a package.json — Xpressify walks up to find the project root.

If generate refuses with "Refusing to create file outside of project root", the path you provided resolved outside your project (for example ../../foo). Drop the escaping segments and use a path inside the project.


Upgrading

To 2.2.2

  • BREAKING (generate): g class, g interface, and g enum without an explicit path used to land next to the current working directory. They now write to src/classes/, src/interfaces/, and src/enums/ under the detected project root, matching the behaviour of every other generator (route, middleware, util, dto, test). Explicit path arguments (g class src/models/User) are unaffected.

From 1.x to 2.x

Version 2.0.0 is a breaking release — generated projects now use ESM instead of CommonJS, and the generate command argument was renamed from the broken <n> placeholder to <component-name>. Existing projects scaffolded by 1.x are not affected; only newly generated projects get the new defaults. See CHANGELOG.md for the full list of changes.


Development

git clone https://github.com/davids199005-oss/xpressify.git
cd xpressify
npm install
npm run dev       # tsup in watch mode

Useful scripts:

npm run build          # production build with tsup
npm run typecheck      # tsc --noEmit
npm run lint           # ESLint
npm run test           # Vitest
npm run test:coverage  # Vitest + coverage report

The CLI binary is bundled with all node_modules inlined (except figlet, which reads its .flf font files at runtime). This is deliberate — several direct dependencies are ESM-only and cannot be loaded via require() from a CJS bundle. See tsup.config.ts for the exact configuration.


License

MIT © David Veryutin