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

@swtt/core

v0.1.1

Published

Framework-free runtime for swtt-js apps: Mongo connection, validation, an error contract that survives the network, and DTO helpers.

Readme

@swtt/core

The framework-free runtime behind swtt-js. Five modules, no domain content, no cloud SDK.

You do not usually install this directly — npx @swtt/cli init my-app scaffolds an app that depends on it.

npm install @swtt/core mongoose zod

mongoose and zod are peer dependencies, so your app owns their versions. mongoose is optional: a client-only consumer importing @swtt/core/errors and @swtt/core/http never needs it.

Entry points

The barrel pulls in mongoose. On a client, import the subpath instead — these bundle onto a phone:

import { getApiErrorText } from "@swtt/core/errors";   // client-safe
import { ApiClient } from "@swtt/core/http";           // client-safe
import { connectDb, model } from "@swtt/core";         // server only

The error contract

details is a required property, not an optional one. An empty array is a deliberate statement; an omitted array is a compile error. This exists because the most common failure in generated apps is a UI that renders message and silently drops the per-field reasons the server already sent.

throw AppError.conflict("That reference is taken.", [
  { path: "reference", message: "already used by invoice INV-14", code: "not_unique" },
]);

getApiErrorText(e) is the only renderer, and it lives here rather than in each app so the newest form cannot drop half the response:

That reference is taken.
reference: already used by invoice INV-14

The contract survives the network. The server serialises AppError.toPayload(); ApiClient rebuilds it with AppError.fromPayload(). A Zod issue raised in a domain operation therefore arrives at a screen still attached to the field it came from, on any platform.

What each module does

| Module | | |---|---| | db | connectDb() — reads process.env.MONGO_URI and nothing else. Caches the connection; bufferCommands: false so a missing one fails loudly. | | model | model(name, schema) — reuses a compiled model so a hot reload cannot throw OverwriteModelError. | | errors | AppError, getApiErrorText, the payload types. Imports nothing. | | http | ApiClient — typed fetch that rebuilds AppError from any non-2xx body, times out at 30s, and synthesises a payload when the body is not one. | | validation | parseInput (every Zod issue becomes one addressable detail) plus objectId, slug, externalUrl, text, isoDate. | | dto | baseDto, id/idOrNull, iso/isoOrNull, Page<T>. |

externalUrl rejects anything but http/https. That is a security control, not tidiness: the value ends up in an href, and javascript: there is script execution — which Zod's .url() accepts.

Documentation

Full reference: docs/systems/core-runtime.md. The reasoning lives in the ADRs under docs/decisions/.

License

Apache-2.0