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

basic-bro

v0.0.5

Published

> A tiny, dependency-free Node framework with batteries included: > HTTP server, routing, middleware, validation, and a lightweight JSX runtime.

Downloads

393

Readme

basic-bro

A tiny, dependency-free Node framework with batteries included: HTTP server, routing, middleware, validation, and a lightweight JSX runtime.

basic-bro is an experiment in building a fully-standalone web stack:

  • No giant framework dependency.
  • No hidden magic – Everything is explicit TypeScript. You can read the source and understand what’s going on.
  • Server + client helpers that are just TypeScript + Node + DOM.
  • Composable – Middleware, routers, and validation are all composable functions.
  • Strict but friendly types – Designed to scale from “simple script” to more serious projects.

Batteries included, not welded in – You get compression, cors, static, logging, sessions, etc., but you can also swap them out or write your own.

Later on, there will be optional helpers for Postgres and friends – but those will be thin wrappers around libraries you install and control.


Features

🔧 Server (Node) – basic-bro/server

  • Minimal but powerful app + router:
    • Express-ish app.get('/path', ...handlers) and nested routers.
    • Route params (/users/:id) with automatic parsing.
    • Per-route middleware, nested handlers, pattern-based routes.
  • Built-in middleware (no external deps):
    • cors() – CORS headers.
    • compression() – gzip/deflate/brotli, content-aware.
    • serveStatic() – static files from public/, with path safety.
    • logger() – request logging with levels and colors.
    • rateLimit() – simple in-memory rate limiting.
    • sessions() – cookie/session helper.
    • jwt() (planned / WIP) – sign/verify helpers for stateless auth.
  • Nice response helpers:
    • res.status(code)
    • res.header(name, value)
    • res.json(body)
    • res.text(body)
    • res.html(body)
    • res.send(body) – smart fallback for strings, buffers, JSON, etc.
  • OpenAPI support (via your validation library):
    • As you define routes & schemas, OpenAPI can be generated automatically.
  • 100% TypeScript-first – generics for req/res extensions, middleware, etc.

🎨 Client (browser) – basic-bro/client

  • Tiny, React-style JSX runtime:
    • h(type, props, ...children) factory.
    • Fragment support: <> ... </>.
    • Function components: const Button = (props) => <button>...</button>.
  • No virtual DOM – just real DOM nodes:
    • Components render once; state can be wired with simple signals (no diffing).
  • Lives in public/js (or similar) – you decide the bundler / build step.
  • Works great with TypeScript + jsxFactory: "h" + jsxFragmentFactory: "Fragment".

✅ Validation – (integrated / recommended)

basic-bro is designed to pair with your validation / schema library:

  • Declarative schemas: v.object({ email: v.string().email(), ... }).
  • Runtime validation: schema.validate(input).
  • validate() middleware to check body, query, params etc.
  • OpenAPI generation: openapi({ routes: [...] }) from schemas.

Installation

Note: Names are placeholders. Adjust to your actual package names.

pnpm add basic-bro

Quick start - Server

// src/server/index.ts
import http from 'node:http';
import path from 'node:path';
import {
	app as createApp,
	router,
	cors,
	compression,
	logger,
	sessions,
	rateLimit,
	serveStatic,
	v,
	validate,
} from 'basic-bro/server';

const publicDir = path.join(__dirname, '..', 'public');

const app = createApp({
	title: 'basic-bro demo',
	docsPath: '/docs',
	staticPath: publicDir,
});

app.use(logger());
app.use(cors());
app.use(compression());
app.use(sessions());

const api = router('/api');

const HealthResponse = v.object({ ok: v.boolean() });

api.get('/health', (_req, res) => {
	res.json({ ok: true });
});

const UserParams = v.object({ id: v.string().min(4) });

api.get('/users/:id', validate({ params: UserParams }), (req, res) => {
	res.json({ userId: req.params.id });
});

api.get('/limited', rateLimit({ windowMs: 60_000, max: 10 }), (_req, res) => {
	res.json({ ok: true, note: 'You can only hit this 10 times per minute' });
});

app.use(api);

const server = http.createServer(app.handle);

server.listen(3000, 'localhost', () => {
	console.log('basic-bro server running at http://localhost:3000');
});

Response Helpers

app.get('/hello', (_req, res) => {
	res.status(200).text('Hello from basic-bro!');
});

app.get('/json', (_req, res) => {
	res.json({ hello: 'world' }); // sets content-type + JSON.stringify
});

app.get('/html', (_req, res) => {
	res.html('<h1>Hello</h1><p>From basic-bro</p>');
});

// Smart send:
app.get('/smart', (_req, res) => {
	res.send({ ok: true }); // => JSON
	// res.send(Buffer.from('raw')); // => octet-stream
});

Sessions and Rate Limiting

import { sessions, rateLimit } from 'basic-bro/server';

app.use(sessions({ secret: 'super-secret-key' }));

app.get('/session-demo', (req, res) => {
	const count = (req.session?.count ?? 0) + 1;
	req.session.count = count;
	res.json({ visits: count });
});

app.get(
	'/rate-limited',
	rateLimit({ windowMs: 10_000, max: 3 }),
	(_req, res) => {
		res.json({ ok: true });
	}
);

Quick Start – Client (JSX Runtime)

// src/client/runtime.ts
import {
	Child,
	Component,
	h,
	Fragment,
	state,
	textSignal,
} from 'basic-bro/client';

// Example component
export const Counter: Component = () => {
	const count = state(0);

	return (
		<button onClick={() => count.set(count.get() + 1)}>
			Clicked {textSignal(count)} times
		</button>
	);
};

Attach to the Dom

// src/client/main.ts
import { Counter } from './runtime';

const app = document.getElementById('app');
if (app) {
	app.innerHTML = '';
	app.appendChild(Counter());
}

Validation & OpenApi

import { app, router, v, openapi, HttpMethod } from 'basic-bro/server';

const app = createApp({
	title: 'My API',
	docsPath: '/docs', //Exposed to /docs by default
});

const api = router('/api');

const User = v.object({
	email: v.string().email(),
	name: v.string().min(2),
});

const Ok = v.object({ ok: v.boolean() });

api.post('/users', validate({ body: User }), (req, res) => {
	const user = req.body; // typed from schema
	res.json({ ok: true, user });
});

// Under the hood, routes can be fed into openapi(...)
const docs = openapi({
	title: 'My API',
	version: '1.0.0',
	routes: [
		openapi.route({
			method: HttpMethod.POST,
			path: '/api/users',
			requestBody: User,
			responses: { 200: Ok },
		}),
	],
});

RoadMap

Roadmap / Ideas

Planned / experimental:

  • Core:

    • App + router with nested handlers and per-route middleware
    • Static file serving
    • CORS, compression, logging, sessions, rate limiting
    • JSX runtime with signals-based reactivity
  • Server:

    • JWT middleware (jwt()): sign/verify, attach req.user
    • Better template helpers (HTML layouts, partials, etc.)
  • Client:

    • Small “hooks” layer for state/effects
    • Simple router for SPA-style navigation
  • Data:

    • PG helpers & DB “bro”: thin wrapper around pg or other drivers
    • You install the DB driver; basic-bro gives you a typed, reusable wrapper

Status

This is early-stage and APIs may change frequently.

If you’re trying it out and something feels off, over-complicated, or under-powered, open an issue or tweak the README to match what you actually implemented.

License

Open source MIT