Open source toolkit
The boring parts of shipping a TypeScript library, already solved.
Here is one library going from source to release in four steps, using four of the packages. Each installs on its own and none of them need the others.
Build it without a config file.
Packem reads the entry points out of the exports you already declared, so there is no second list of files to keep in step with package.json.
// package.json
{
"exports": {
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
},
"types": "./dist/index.d.ts"
}
$ packem build
// CJS and ESM, .d.ts bundled, dependencies
// externalised. No config file required.Next, see what it does at runtime
Watch what it does.
Readable badges while you work, structured JSON in production, and the same logger in Node, at the edge and in the browser. Repeated lines get collapsed instead of flooding the output.
import { pail } from "@visulima/pail";
pail.success("Operation successful");
pail.pending("Write release notes for %s", "1.2.0");
pail.fatal(new Error("Unable to acquire lock"));
// Or configure your own instance
import { createPail } from "@visulima/pail";
const logger = createPail({ logLevel: "warn" });
logger.info("Filtered out");
logger.force.info("Logged anyway");Next, give it a command line
Give it a command line.
Commands, flags and arguments, with the help output generated from the same definition, so the documentation cannot drift from the parser. Runs on Node, Deno and Bun.
import { Cerebro } from "@visulima/cerebro";
const cli = new Cerebro("my-cli");
cli.addCommand({
name: "build",
description: "Build the project",
options: [
{
name: "output",
alias: "o",
type: String,
defaultValue: "dist",
},
{ name: "watch", alias: "w", type: Boolean },
],
execute: ({ logger, options }) => {
logger.info(`Building to ${options.output}`);
},
});
await cli.run();Last, keep the repository honest
Keep the repository honest.
One toolkit for the chores: a task runner with a cache, staged-file hooks, secret scanning, and a pinned installer so a fresh clone resolves the same tree. This site is built with it.
// vis.config.ts
import { defineConfig } from "@visulima/vis/config";
export default defineConfig({
install: { backend: "aube" },
staged: {
"*.{ts,tsx}": ["eslint --fix", "prettier --write"],
"package.json": (files) =>
`sort-package-json ${files.join(" ")}`,
},
});Most installed
The four above are the walkthrough. These are the ones that quietly turn up in the most lockfiles.
What is in there
One monorepo, released package by package. Take the two you need and leave the rest.
Tested on the runtimes you ship to.
Every package targets modern Node and is verified against the alternative runtimes before release.
Use it, break it, tell us
Everything is developed in public. Open an issue, send a patch, or just take the package and go.
