Skip to content
Back to skills

Builder Factory

ASecurity

Use this skill to create typed test data builders with mimicry-js and Faker for any TypeScript interface or type. Invoke whenever the user asks to generate mock data, create test fixtures, build factory functions, produce seed data, or construct fake objects for unit tests, Storybook stories, or E2E scenarios. Also use when migrating from test-data-bot or Fishery to mimicry-js, or when the user mentions builders, factories, or typed mock/fake/test/seed data generation — even if they describe ...

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 11, 2026
developmenttypescriptgotestingapidatabase

Works with

  • api

Security analysis

A100/100

Pro scans all 4 files and shows the line behind each finding

Scanned November 11, 2026

npx -y skills add JanSzewczyk/claude-plugins --skill builder-factory --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Builder Factory?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Builder Factory
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/janszewczyk-builder-factory-claude-plugins/badge)](https://www.skillsdirectory.com/skills/janszewczyk-builder-factory-claude-plugins)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: builder-factory
description: Use this skill to create typed test data builders with mimicry-js and Faker for any TypeScript interface or type. Invoke whenever the user asks to generate mock data, create test fixtures, build factory functions, produce seed data, or construct fake objects for unit tests, Storybook stories, or E2E scenarios. Also use when migrating from test-data-bot or Fishery to mimicry-js, or when the user mentions builders, factories, or typed mock/fake/test/seed data generation — even if they describe the task indirectly (e.g. "I need realistic invoices for testing" or "generate sample users for my stories").
allowed-tools: Read, Write, Edit, Glob, Grep
---

# Builder Factory Generator

Generate `mimicry-js` + `@faker-js/faker` factory builders for TypeScript types (for Vitest, Storybook,
E2E, and dev seeding). This file is the API and rules; full builder examples are in the reference.

> - [references/field-mappings.md](./references/field-mappings.md) — field type → Faker method mappings.
> - [references/examples.md](./references/examples.md) — complete builders: traits, postBuild, nested/deep-merge,
>   database types, discriminated unions, composition, recursive types, seeding, `withPrev`, reset.

Check `CLAUDE.md` for the **Faker locale**, **builder location convention**, and **database type patterns**
before generating.

## Workflow

1. **Find existing builders first** — `Glob` for `**/*.builder.ts` and `features/*/test/builders/*.ts`;
   reuse before creating.
2. **Analyze the type** — fields, nested types, arrays, optional/Date/enum/union fields.
3. **Place the file** — feature-specific `features/[feature]/test/builders/` or shared `tests/builders/`.
4. **Name it** — `camelCase(TypeName) + "Builder"`, file `kebab-case.builder.ts`
   (`UserProfile` → `userProfileBuilder` in `user-profile.builder.ts`). Include JSDoc with usage examples.

## Builder API

**Methods** — `.one(options?)` (single), `.many(count, options?)` (array), `.reset()` (reset
`sequence`/`unique`/iterators). Options: `overrides` (Partial<T>), `traits` (string | string[]),
`postBuild` ((obj) => obj, per-call).

**Field generators** (place as field values — see placement rules):

- `sequence()` / `sequence((n) => \`prefix-\${n}\`)` — auto-increment.
- `oneOf("a", "b")` — random from options; `unique([...])` — each value once, throws when exhausted.
- `bool()`, `int(min?, max?)` (default 1–1000), `float(min?, max?)` (default 0–1).
- `withPrev((prev?) => value)` — access the previous build value.
- `fixed(fn)` — keep a function value as-is (don't call it).
- `() => value` — plain function, fresh each build (replaces `perBuild`). Static values need no wrapper.

**Deterministic random** — `seed(value)` makes `oneOf`/`int`/`float`/`bool` reproducible; `getSeed()` reads it.

## Features (code in examples.md)

- **Traits** — named variants (`build({ traits: { admin: { overrides: { role: "admin" } } } })`), applied
  via `.one({ traits: "admin" })` or an array.
- **postBuild** — compute fields from siblings after the object is built (e.g. a total from line items).
- **Nested builders** — `field: () => otherBuilder.one()`; overrides deep-merge (patch one nested key
  without replacing the object).
- **Database types** — separate Base (no id/timestamps) and Application (id + Date timestamps) builders.

## Rules

The rules below are generated from the shared knowledge notes: generator placement, `.one()` /
`.many()` with overrides and traits, `fixed()`, `postBuild`, nested builders, `unique()`, resetting
state. Open a rule in [rules.md](./references/rules.md) when the builder you are writing touches it.

<!-- BEGIN:knowledge -->
<!-- generated by knowledge.mjs from 12 note(s) (sha256 cf4fa24048d6); edit the notes in knowledge/, then run build -->

| Impact | Rule | Applies to |
| --- | --- | --- |
| critical | [Place mimicry-js generators directly as field values, use Faker inside arrow functions](references/rules.md#place-mimicry-js-generators-directly-as-field-values-use-faker-inside-arrow-functions) — oneOf, int, sequence and friends resolve only at field level; inside () => they return a descriptor, not a value. | typescript, mimicry-js |
| high | [Set every value the test asserts on explicitly when you build test data](references/rules.md#set-every-value-the-test-asserts-on-explicitly-when-you-build-test-data) — Let the builder randomise what the test ignores; pass an override for every value the test checks. | any |
| high | [Wrap function-typed fields in fixed() so the builder does not call them](references/rules.md#wrap-function-typed-fields-in-fixed-so-the-builder-does-not-call-them) — A plain function as a field value is called on every build; fixed(fn) keeps it as the value. | typescript, mimicry-js |
| high | [Build with .one() and .many() and pass overrides or traits for asserted values](references/rules.md#build-with-one-and-many-and-pass-overrides-or-traits-for-asserted-values) — userBuilder.one({ overrides }) for one object, .many(n) for lists, traits for named states. | typescript, mimicry-js |
| high | [Write TypeScript builders with mimicry-js and Faker](references/rules.md#write-typescript-builders-with-mimicry-js-and-faker) — Every builder uses mimicry-js with Faker; not test-data-bot or Fishery, and not a hand-written factory. | typescript, mimicry-js |
| medium | [Reset builder counters and random state between tests that depend on them](references/rules.md#reset-builder-counters-and-random-state-between-tests-that-depend-on-them) — Sequences and seeded randomness carry over between tests; reset them where a test depends on their values. | any |
| medium | [Build structured test data with a builder, not inline object literals](references/rules.md#build-structured-test-data-with-a-builder-not-inline-object-literals) — Typed objects with three or more fields come from a shared builder; reuse an existing one before writing one. | any |
| medium | [Fill nested typed objects from their own builder](references/rules.md#fill-nested-typed-objects-from-their-own-builder) — A nested type gets its own builder, used as () => otherBuilder.one(); overrides deep-merge into it. | typescript, mimicry-js |
| medium | [Build lists with .many(count), not Array.from or map](references/rules.md#build-lists-with-manycount-not-arrayfrom-or-map) — .many(n) applies overrides and traits to each item and keeps sequence and unique state right. | typescript, mimicry-js |
| medium | [Compute fields that derive from other fields in postBuild](references/rules.md#compute-fields-that-derive-from-other-fields-in-postbuild) — Totals, counts and display names built from sibling fields go in postBuild, so overrides stay consistent. | typescript, mimicry-js |
| medium | [Call builder.reset() in beforeEach when a test depends on sequence values](references/rules.md#call-builderreset-in-beforeeach-when-a-test-depends-on-sequence-values) — reset() restarts sequence() and unique() counters; seed() makes oneOf, int, float and bool reproducible. | typescript, mimicry-js |
| medium | [Use unique() for values that must differ across built objects](references/rules.md#use-unique-for-values-that-must-differ-across-built-objects) — oneOf() can repeat a value within one .many() call; unique() hands each value out once. | typescript, mimicry-js |

<!-- END:knowledge -->

Also:

- **Prefer `oneOf` / `int` / `float` / `bool` over Faker** at top level — they integrate with `seed()`.
- **`faker.helpers.weightedArrayElement`** for non-uniform distributions (Faker only).
- `sequence()` for numeric ids, `() => faker.string.uuid()` for UUIDs.

Files in this skill

  • SKILL.md7.5 KB
  • references/examples.md9.9 KB
  • references/field-mappings.md3.8 KB
  • references/rules.md10.7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

View all in development →

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.