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

@forinda/kickjs

v6.5.1

Published

A production-grade, decorator-driven Node.js framework for TypeScript — runs on Express, Fastify, or h3 (swap the engine in one line).

Downloads

2,243

Readme

@forinda/kickjs

Decorator-driven Node.js framework for TypeScript — runs on Express, Fastify, or h3 (swap the engine in one line). Custom DI container, factory-first module system, code generators, Zod-native validation, end-to-end type safety via typegen, and Vite HMR for sub-200ms dev reloads.

Install

# Scaffold a new project (recommended) — gets you a complete layout in seconds
npx @forinda/kickjs-cli new my-api && cd my-api && pnpm dev

# Or add to an existing project (Express is the zero-config default engine)
pnpm add @forinda/kickjs express reflect-metadata zod
pnpm add -D @forinda/kickjs-cli @forinda/kickjs-vite

# Prefer another engine? Install its peer and swap one line (see HTTP Runtimes):
#   pnpm add fastify @fastify/middie   →  runtime: fastifyRuntime()
#   pnpm add h3                        →  runtime: h3Runtime()

Getting Started

The CLI scaffolds a complete layout. The files below show the canonical shapes — copy them into an existing project if you're not using kick new.

1. Service (@Service + DI)

// src/modules/users/user.service.ts
import { Service } from '@forinda/kickjs'

@Service()
export class UserService {
  list() {
    return [{ id: '1', name: 'Alice' }]
  }

  create(input: { name: string; email: string }) {
    return { id: '2', ...input }
  }
}

2. Controller (@Controller, decorators, typed ctx)

// src/modules/users/user.controller.ts
import { Controller, Get, Post, Autowired, type Ctx } from '@forinda/kickjs'
import { z } from 'zod'
import { UserService } from './user.service'

const createUserSchema = z.object({
  name: z.string().min(1),
  email: z.string().email(),
})

@Controller()
export class UserController {
  @Autowired() private readonly users!: UserService

  @Get('/')
  list(ctx: Ctx<KickRoutes.UserController['list']>) {
    ctx.json(this.users.list())
  }

  @Post('/', { body: createUserSchema, name: 'CreateUser' })
  create(ctx: Ctx<KickRoutes.UserController['create']>) {
    // ctx.body is validated + typed from the Zod schema
    ctx.created(this.users.create(ctx.body))
  }
}

Ctx<KickRoutes.UserController['list']> is generated by kick typegen (auto-runs on kick dev) — ctx.params, ctx.body, ctx.query all narrow to the Zod-derived shape as you save.

3. Module (defineModule() factory)

// src/modules/users/user.module.ts
import { defineModule } from '@forinda/kickjs'
import { UserController } from './user.controller'

export const UserModule = defineModule({
  name: 'UserModule',
  build: () => ({
    routes() {
      return { path: '/users', controller: UserController }
    },
  }),
})

The framework derives the router from controller — never import buildRoutes directly. path is the single source of truth for the mount prefix; @Controller() takes no path argument.

4. Module registry (defineModules() fluent chain)

// src/modules/index.ts
import { defineModules } from '@forinda/kickjs'
import { UserModule } from './users/user.module'

// Factories are called at the registration site — `UserModule()` produces
// the AppModule instance bootstrap registers. Each `.mount(...)` call adds
// one module; chain as many as you need.
export const modules = defineModules().mount(UserModule())

5. Bootstrap entry

// src/index.ts
import 'reflect-metadata'
import './config' // side-effect — registers env schema BEFORE bootstrap runs
import { bootstrap } from '@forinda/kickjs'
import { modules } from './modules'

// Always export the app. The Vite plugin reads this symbol to wire HMR;
// skipping `export` works in production but degrades dev mode to full restarts.
export const app = await bootstrap({ modules })

That's it — http://localhost:3000/api/v1/users returns Alice; POST /api/v1/users with { name, email } validates against the Zod schema.

HTTP Runtimes — Express, Fastify, or h3

The HTTP engine is pluggable. Controllers, DI, decorators, and ctx are engine-neutral; pick the engine in bootstrap() (Express is the default — no import needed):

import { bootstrap } from '@forinda/kickjs'
import { fastifyRuntime } from '@forinda/kickjs/fastify' // or @forinda/kickjs/h3 → h3Runtime

export const app = await bootstrap({ modules, runtime: fastifyRuntime() })

kick new --runtime express|fastify|h3 scaffolds the right peers. File uploads (@FileUploadctx.file / ctx.files) and the rest of the surface work the same on all three. See HTTP Runtimes.

Two web-standard entries sit alongside them (h3 v2 engine — additive, the v1 runtime is untouched):

import { h3WebRuntime } from '@forinda/kickjs/h3-web' // bootstrap() on node, WHATWG pipeline
import { createWebApp } from '@forinda/kickjs/web' // fetch(Request) → Response — Workers / Bun / Deno
import * as h3 from 'h3' // v2 — passed in: edge bundlers have no createRequire
import { modules } from './modules'

const app = createWebApp({ h3, modules })
export default { fetch: (req: Request) => app.fetch(req) }

See Edge Deployment.

Project Layout

kick new produces this convention; everything except the bootstrap entry is configurable via kick.config.ts:

src/
  index.ts                  # bootstrap entry — exports `app`
  config/index.ts           # env schema via defineEnv() + loadEnv()
  modules/
    index.ts                # defineModules() chain
    <name>/<name>.module.ts # one module per feature
    <name>/<name>.controller.ts
    <name>/<name>.service.ts
  middleware/               # optional — `@Middleware()` factories + global stack
  adapters/                 # optional — `defineAdapter()` integrations
  plugins/                  # optional — `definePlugin()` bundles
.agents/                    # AI agent context — AGENTS.md + skills/<slug>/SKILL.md
CLAUDE.md                   # Claude Code root (thin pointer to .agents/)
kick.config.ts              # CLI configuration (optional)
vite.config.ts              # Vite + KickJS HMR

Core Concepts

  • Pluggable HTTP runtimes — one HttpRuntime seam over Express (default), Fastify, or h3. Swap the engine in one line; everything above stays the same. See HTTP Runtimes.
  • Return-value handlers + typed clientreturn the payload (reply(201, body) for other statuses) and the response type flows through kick typegen into KickRoutes.Api, consumed by @forinda/kickjs-client on the frontend. Declare { response: schema } on a route and the same contract feeds the OpenAPI success response. See Controllers, Typed Client.
  • First-class databasekick/db: code-first schema, fully typed queries, and migrations for PostgreSQL / SQLite / MySQL. kick add db (or pg / sqlite / mysql). See Database.
  • Custom DI container — three scopes (singleton / transient / request), slash-delimited tokens (createToken<T>('app/users/repository')), constructor + property injection. No external DI dep. See Dependency Injection.
  • Factory-firstdefineAdapter(), definePlugin(), defineModule(), defineHttpContextDecorator(). No class hierarchies to inherit from. See Adapters, Plugins.
  • Context Contributors — replace single-purpose middleware that only sets ctx values. Typed dependsOn (typos are TS errors, not boot-time crashes), topo-sorted at startup, runs across HTTP / WS / queue / cron. See Context Decorators.
  • Env wiringdefineEnv() + loadEnv() in src/config/index.ts. The import './config' side-effect import at the top of src/index.ts MUST happen before any @Value() injection resolves. See Configuration.
  • Asset Manager — typed assets.<ns>.<key>() accessor, configured via assetMap in kick.config.ts. Drops the __dirname arithmetic that production builds get wrong. See Asset Manager.
  • Reactive primitivesref() / computed() / reactive() / watch() Vue-style; ref and computed auto-unwrap on JSON.stringify so they drop straight into introspect() snapshots.
  • DevTools/_debug browser panel with topology, container, contributors, metrics. Adapters expose state via introspect(): IntrospectionSnapshot (type lives in @forinda/kickjs — no extra import needed). See DevTools.

Common Add-Ons

kick add db           # kick/db — typed, code-first DB (+ pg / sqlite / mysql)
kick add upload       # file-upload driver for your runtime (multer / @fastify/multipart / native)
kick add swagger      # OpenAPI docs from decorators + Zod schemas
kick add devtools     # /_debug dashboard
kick add ws           # WebSocket with @WsController, rooms, heartbeat
kick add queue        # BullMQ / RabbitMQ / Kafka jobs
kick add testing      # createTestApp + createTestModule helpers
kick add --list       # full live catalog

kick doctor           # pre-flight checks: engine peers, upload driver, env wiring

Documentation

kickjs.app — full guide, API reference, BYO recipes (auth, GraphQL, OTel, cron, mailer, multi-tenancy, notifications), example apps.

Start here:

License

MIT