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

@vernali/core

v0.2.0

Published

Core functionality for Vernali framework. POC for now, will be expanded in the future.

Readme

@vernali/core

npm version license type: module

Core runtime for the Vernali framework. Provides a minimal, composable HTTP layer built directly on top of Node.js native http primitives, without any third-party runtime dependencies.

Note: @vernali/contracts is a dependency of this package and provides the shared interface types. @vernali/core is designed as a minimalist middleware layer — lightweight by intent, with no runtime dependencies beyond Node.js itself.


Requirements

  • Node.js ≥ 18 (native ESM support required)
  • TypeScript ≥ 6.x (for type-checked usage)

Installation

npm install @vernali/core

Peer dependencies (optional, required only if using the view rendering engine):

npm install ejs     # for EJS template support
npm install pug     # for Pug template support

Architecture Overview

@vernali/core follows a layered middleware composition pattern. Each incoming HTTP request is processed through a pipeline:

IncomingMessage + ServerResponse
        │
        ▼
  Application.handleRequest()
        │
        ├── loadContext()       ← body parsing (POST/PUT/PATCH)
        │
        ├── dispatch()          ← router.handle(ctx)
        │   │
        │   └── Router.#dispatch()
        │         │
        │         └── Layer.matches() → compose(handlers)(ctx, next)
        │
        ├── handleNotFound()    ← 404 fallback
        │
        └── handleError()       ← 500 error boundary

The Router uses a Layer stack where each Layer encapsulates a path pattern, an optional HTTP method, and an ordered list of handlers. Path matching supports static paths, named parameters (:param), wildcard (*), and RegExp patterns.


API Reference

Application

The central application class. Exposes the full routing DSL and the ready() callback for integration with a native http.Server.

import { Application } from '@vernali/core'
import { createServer } from 'node:http'

const app = new Application()

app.get('/health', (ctx) => {
  ctx.json({ status: 'ok' })
})

createServer(app.ready()).listen(3000)

Constructor options

new Application(options?: {
  dispatch?:    (ctx: Context) => Promise<void>
  onNotFound?:  (ctx: Context) => Promise<void>
  onError?:     (err: unknown, ctx: Context) => Promise<void>
})

All three hooks are optional and override the built-in default behaviors:

| Option | Default behavior | |---|---| | dispatch | Routes request through the internal Router | | onNotFound | Returns 404 Not Found as plain text | | onError | Logs to console.error, returns 500 Internal Server Error |

Routing methods

All routing methods return this for chaining and accept one or more handler functions.

app.get(path, ...handlers)
app.post(path, ...handlers)
app.put(path, ...handlers)
app.patch(path, ...handlers)
app.delete(path, ...handlers)
app.all(path, ...handlers)          // matches all HTTP methods
app.use([path], ...handlers)        // mounts middleware or sub-routers

path accepts: string (static or parameterized), RegExp, or '*' (wildcard).

app.use() — Mounting sub-routers

import { Application, Router } from '@vernali/core'

const api = new Router()
api.get('/users', listUsers)
api.post('/users', createUser)

const app = new Application()
app.use('/api/v1', api)

app.setViews(engine, viewsDir)

Configures the template engine and the views directory for ctx.render().

app.setViews('ejs', './views')
app.setViews('pug', './templates')

app.serveStatic(rootDir, options?)

Returns a middleware that serves static assets from rootDir. Handles directory index resolution (index.html by default), MIME type detection, path traversal protection, and HEAD requests.

app.use(app.serveStatic('./public'))
// or scoped to a prefix:
app.use('/static', app.serveStatic('./assets'))

app.ready()

Returns a (req, res) => void callback suitable for http.createServer().


Router

A standalone, nestable router. Shares the same routing DSL as Application.

import { Router } from '@vernali/core'
// or via the named export:
import { Router } from '@vernali/core/router'

const router = new Router()

router.get('/items',      listItems)
router.get('/items/:id',  getItem)
router.post('/items',     createItem)
router.delete('/items/:id', deleteItem)

Routers can be nested to arbitrary depth via app.use() or router.use().


Context

The request/response abstraction passed to every handler. Wraps IncomingMessage and ServerResponse and provides a unified API surface.

Properties

| Property | Type | Description | |---|---|---| | req | IncomingMessage | Raw Node.js request object | | res | ServerResponse | Raw Node.js response object | | method | string | HTTP method in uppercase | | path | string | Current path segment being matched (mutated during sub-router dispatch) | | originalUrl | string | Unmodified request URL | | baseUrl | string | Accumulated matched prefix | | params | Record<string, string> | Named route parameters (e.g. :id) | | query | Record<string, string> | Parsed query string values | | searchParams | URLSearchParams | Raw URLSearchParams instance | | body | Record<string, any> | Parsed JSON body (populated after body parsing middleware) | | state | Record<string, any> | Arbitrary per-request shared state | | cookies | Record<string, string> | Parsed cookies (populated after cookieParser middleware) | | headers | Record<string, string \| string[]> | Request headers | | requestId | string | Assignable request identifier for tracing | | closed | boolean | Indicates if the response has been terminated |

Response methods

ctx.status(code: number): this                   // sets res.statusCode, chainable
ctx.json(data: Record<string, any>): void        // sends JSON response
ctx.send(data: string): void                     // sends plain text response
ctx.html(content: string): void                  // sends HTML response
ctx.redirect(url: string, code?: number): void   // 302 by default
ctx.setHeader(key: string, value: string): this  // chainable header setter
ctx.render(view, data?, options?): Promise<void> // renders a template

Example — chained status + JSON:

app.get('/error', (ctx) => {
  ctx.status(422).json({ error: 'Unprocessable Entity' })
})

Built-in Middleware

bodyParser

Parses JSON request bodies for POST, PUT, and PATCH requests. Invoked automatically by Application.loadContext().

import { bodyParser } from '@vernali/core'

// Auto-applied by Application. For manual use:
app.use(async (ctx, next) => {
  ctx.body = await bodyParser(ctx)
  await next()
})

cookieParser

Parses the Cookie header and populates ctx.cookies.

import { cookieParser } from '@vernali/core'

app.use(cookieParser)

app.get('/profile', (ctx) => {
  const token = ctx.cookies['auth_token']
  // ...
})

Path Matching Reference

| Pattern | Matches | |---|---| | /users | Exact path /users | | /users/:id | /users/123, exposes ctx.params.id | | /files/* (wildcard) | Any path under /files/* | | RegExp | Custom expression evaluated against ctx.path | | '/' in use() | Matches any path (prefix-based) |

For use() mounts, matching is prefix-based — the consumed prefix is stripped from ctx.path before the handler or sub-router is invoked. For route methods (get, post, etc.), matching is exact.


View Rendering

ctx.render() supports three engines:

| Engine | Package | Template extension | |---|---|---| | html | built-in | .html | | ejs | ejs (peer dep) | .ejs | | pug | pug (peer dep) | .pug |

app.setViews('ejs', './views')

app.get('/page', async (ctx) => {
  await ctx.render('home', { title: 'Home', user: ctx.state.user })
})

The built-in HTML engine supports {{ variable }} interpolation with automatic HTML escaping. Nested property access is supported via dot notation ({{ user.name }}).


Package Exports

The package exposes two public entry points:

| Specifier | Entry point | Description | |---|---|---| | @vernali/core | dist/index.js | Main exports: Application, Context, Router, bodyParser, cookieParser and types | | @vernali/core/router | dist/lib/router/index.js | Standalone Router export |


Development Scripts

npm run build        # clean + tsc compile to ./dist
npm run type-check   # tsc --noEmit (no output, type validation only)
npm run dev          # watch mode via nodemon
npm run lint         # StandardJS lint
npm run lint:fix     # StandardJS lint with auto-fix

Type Contracts

All public interfaces are defined in @vernali/contracts and re-exported where appropriate. The types enforced in this package include:

  • IApplication<Ctx> — implemented by Application
  • IRouter<Ctx> — implemented by Router
  • ILayer<Ctx> — implemented by Layer
  • IMiddlewareFn<Ctx> — the middleware function signature (ctx, next?) => Promise<void>
  • IContext — base context interface
  • IBodyParser — body parsing contract
  • IServerOptions, ILogger — server and logging interfaces

License

ISC © Yael De Jesus