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

@sahinur/forgedata

v0.2.0

Published

A modern, modular, tree-shakable, zero-dependency fake data generator for TypeScript and JavaScript. A production-ready alternative to Faker.js with React integration and a CLI.

Readme

⚒️ ForgeData

A modern, modular, tree-shakable, zero-runtime-dependency fake data generator for TypeScript and JavaScript.

A production-ready alternative to Faker.js — with React integration and a CLI built in.

npm version npm downloads CI coverage bundle size types license

Website  ·  Try it live  ·  Docs  ·  npm  ·  GitHub


  • 100+ generators across 16 modules (forge.listGenerators() to see every one)
  • Zero runtime dependencies
  • ESM + CommonJS, one package
  • Works in Node.js, Bun, Deno, and browsers — no runtime-specific APIs, only web-standard globals (btoa, crypto-free PRNG)
  • 100% typed, every generator has a precise return type
  • Tree-shakable — import only the modules/functions you use
  • Seedable — deterministic output for tests and snapshots
  • 9 built-in locales, plus a custom locale API
  • Custom generators via forge.define(...)
  • Schema-based generation (@sahinur/forgedata/zod): fake data straight from a Zod schema
  • React integration (@sahinur/forgedata/react): a provider + two hooks
  • CLI (forgedata): generate fake data from your terminal or scripts
  • 100% test coverage (statements/branches/functions/lines)

Table of contents

Install

npm install @sahinur/forgedata

Quick start

import { ForgeData } from "@sahinur/forgedata";

const forge = new ForgeData();

forge.person.fullName();          // "Ava Thompson"
forge.internet.email();           // "[email protected]"
forge.location.country();         // "Canada"
forge.finance.creditCardNumber(); // "4539123456781234"
forge.phone.number();             // "+1-555-123-4567"
forge.ai.prompt();                // "Explain quantum computing to a beginner..."

Or use the ready-made default instance for quick scripts:

import { forge } from "@sahinur/forgedata";

console.log(forge.person.fullName());

Deterministic output (seeding)

const forge = new ForgeData({ seed: 42 });
forge.person.fullName(); // always the same value for seed 42

forge.seed(42);          // reseed an existing instance

Seeds accept a number or a string (strings are hashed into a seed), so you can seed with something readable like a test name.

Locales

const forge = new ForgeData({ locale: "ja" });
forge.person.fullName(); // Japanese name pool

forge.locale("fr");      // switch at runtime
forge.locale();          // "fr" — read the current locale

Built-in locales: en, bn (Bangla), hi (Hindi), ar (Arabic), ja (Japanese), fr (French), de (German), es (Spanish), zh (Chinese).

Custom locales

forge.defineLocale({
  code: "pirate",
  name: "Pirate",
  person: {
    firstNamesMale: ["Blackbeard", "Redbeard"],
    firstNamesFemale: ["Anne", "Mary"],
    lastNames: ["Silver", "Flint"],
    jobTitles: ["First Mate"],
    professions: ["Sailor"],
  },
  location: { cities: ["Tortuga"], states: ["Caribbean"], countries: ["Never Land"] },
  company: { suffixes: ["& Co"], catchPhraseAdjectives: ["Salty"], catchPhraseNouns: ["treasure"] },
  lorem: { words: ["arr", "matey", "doubloon"] },
});

forge.locale("pirate");

Custom generators

forge.define("pokemon", (f) => f.pick(["Pikachu", "Bulbasaur", "Charmander"]));

forge.custom.pokemon(); // "Pikachu"

Unique values

forge.unique.email();    // never repeats for this ForgeData instance
forge.unique.username();
forge.unique.uuid();

const uniqueCity = forge.unique.wrap(() => forge.location.city());
uniqueCity();

forge.unique.clear(); // forget everything generated so far

Helpers & randomness utilities

forge.uuid();
forge.shuffle([1, 2, 3]);
forge.pick(["a", "b", "c"]);
forge.pickMultiple(["a", "b", "c", "d"], 2);
forge.randomEnum(MyEnum);
forge.probability(0.3);
forge.weighted([
  { weight: 9, value: "common" },
  { weight: 1, value: "rare" },
]);
forge.randomArray(() => forge.person.fullName(), 5);

Generator introspection

Every module is walked via prototype introspection rather than a hand-maintained registry, so this never drifts from the real API:

forge.listGenerators();
// [{ module: "person", method: "fullName", id: "person.fullName" }, ...]  (100+ entries)

forge.invoke("person", "fullName"); // same as forge.person.fullName()

This is what the CLI is built on.

Zod schema generation

npm install @sahinur/forgedata zod
import { z } from "zod";
import { fromZodSchema } from "@sahinur/forgedata/zod";

const UserSchema = z.object({
  id: z.string().uuid(),
  name: z.string(),
  email: z.string().email(),
  age: z.number().int().min(18).max(99),
  role: z.enum(["admin", "user", "guest"]),
  tags: z.array(z.string()).min(1).max(3),
  bio: z.string().max(140).optional(),
});

const user = fromZodSchema(forge, UserSchema);
// fully typed as z.infer<typeof UserSchema> — every field respects the
// schema's constraints: a valid uuid, a real-looking email, age in [18, 99],
// one of the three enum values, 1-3 tags, bio present ~80% of the time.

Supports the full range of Zod v4 schema types recursively: primitives (with format-aware strings — .email(), .url(), .uuid(), .datetime(), .ipv4(), .jwt(), and more — plus .min()/.max()/.length()), object, array, tuple, record, map, set, enum/native enums, literal, union/discriminated union, optional/nullable/default/catch, and recursive schemas via z.lazy() (depth-capped, so a self-referential schema can't blow the stack).

.transform()/.pipe() are run through the schema's real safeParse() after generation, so the output reflects the actual post-transform shape. Arbitrary .refine() predicates aren't evaluated ahead of time — a generated value can occasionally fail one, in which case the raw (pre-refine) value is returned rather than throwing. zod is an optional peer dependency (^4.0.0); the main @sahinur/forgedata entry point never imports it, exactly like the React integration.

React integration

import { ForgeDataProvider, useForgeData, useGenerator } from "@sahinur/forgedata/react";

function App() {
  return (
    <ForgeDataProvider seed={42} locale="en">
      <UserCard />
    </ForgeDataProvider>
  );
}

function UserCard() {
  // Regenerated only when `deps` changes — stable across re-renders otherwise.
  const user = useGenerator(
    (forge) => ({ name: forge.person.fullName(), email: forge.internet.email() }),
    [],
  );
  return <div>{user.name} — {user.email}</div>;
}

useForgeData() works even without a ForgeDataProvider (it falls back to a shared default instance) — wrap your tree in a provider whenever you need a specific seed/locale or per-instance isolation. react is an optional peer dependency; the main @sahinur/forgedata entry point never imports it.

CLI

npx --package=@sahinur/forgedata forgedata list                     # every generator id
npx --package=@sahinur/forgedata forgedata list --module person     # filtered to one module
npx --package=@sahinur/forgedata forgedata generate person.fullName # one value
npx --package=@sahinur/forgedata forgedata generate internet.email --count 5 --seed 42
npx --package=@sahinur/forgedata forgedata generate location.country --locale ja --json

Install it globally (npm install -g @sahinur/forgedata) to just run forgedata ... directly; see the docs site for the full flag reference.

Modules

| Module | Examples | |-------------|----------| | person | firstName(), lastName(), fullName(), gender(), jobTitle(), profession() | | internet | email(), username(), password(), url(), domain(), ipv4(), ipv6(), mac(), userAgent(), jwt(), apiKey(), jwtSecret() | | company | name(), catchPhrase(), logo() | | finance | currency(), amount(), creditCardNumber(), creditCardCVV(), iban(), bitcoinAddress(), ethereumAddress(), cryptoCoin(), stockSymbol() | | location | country(), state(), city(), zipCode(), latitude(), longitude(), timezone(), airport() | | commerce | productName(), price(), department(), isbn(), barcode() | | phone | number(), imei() | | date | past(), future(), recent(), birthdate(), month(), weekday(), between() | | image | avatar(), url(), category(), dataUri() | | lorem | word(), words(), sentence(), paragraph(), slug(), markdown(), html() | | color | hex(), rgb(), rgba(), hsl(), cssColorName(), tailwindColor(), materialColor(), svgPattern() | | vehicle | manufacturer(), model(), type(), vin() | | animal | type(), name() | | science | unit(), chemicalElement() | | ai | prompt(), chatConversation(), codeSnippet(), sqlQuery(), json(), markdown(), apiResponse(), logLine(), commitMessage(), issueTitle(), prDescription() | | misc | emoji(), hashtag(), programmingLanguage(), githubUsername(), gitCommitHash(), semver(), dockerImageName(), npmPackageName(), otp(), licenseKey(), qrData(), movie(), book(), music(), food(), holiday(), university() |

Run forge.listGenerators().length to see the exact live count (100+).

Runtime support

ForgeData avoids Node-only APIs in src/ — it uses only btoa, Math/Date, and standard JS, all of which exist in Node 18+, Bun, Deno, and every modern browser. It's published as ESM + CJS so:

  • Node.js: import/require both work out of the box.
  • Bun: works via the same ESM/CJS builds.
  • Deno: import { ForgeData } from "npm:@sahinur/forgedata";
  • Browsers: import { ForgeData } from "@sahinur/forgedata"; through any bundler, or examples/browser.html for a zero-bundler example.

Development

npm install
npm run build            # tsup -> dist (ESM + CJS + .d.ts, for index/react/zod/cli)
npm run test:coverage    # vitest, enforces 100% coverage thresholds
npm run lint
npm run bench            # micro-benchmark, compares against faker if installed
npm run cli -- list      # run the CLI from source during development

See the documentation site (built from docs/docs.html) for the getting-started guide, full API reference, React guide, CLI reference, migration guide from Faker.js, and contributing guide. See examples/ for runnable Node, browser, React, and CLI samples.

Website

docs/ is a plain HTML + Tailwind CSS landing page and single-page documentation site (no framework, no server-side build):

cd docs
npm install
npm run build   # compiles src/input.css -> dist/output.css (commit the result)
npm run serve   # or just open index.html directly

Deployed straight from the repo — no CI needed: Settings → Pages → Source → Deploy from a branch → main / docs. Because there's no build step in that flow, docs/dist/output.css is committed rather than gitignored; run npm run build in docs/ and commit the output whenever you touch docs/src/input.css or add new Tailwind classes to the HTML.

Publishing

This repo is fully set up to publish, but nothing publishes itself:

npm run preflight   # lint + typecheck + 100%-coverage tests + build
npm login
npm publish --access public

scripts/publish.sh wraps that sequence with a confirmation prompt, and RELEASE_NOTES.md has a ready-to-paste description for the GitHub Release / npm announcement.

For every release after the first, .github/workflows/release.yml runs semantic-release on pushes to main — it derives the next version from Conventional Commits, updates CHANGELOG.md, tags, and publishes, but only once you add an NPM_TOKEN repository secret. Until then it's a no-op (see the docs site's Contributing section); it never requires a token to just sit there ready.

License

MIT