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

clearschema

v1.4.0

Published

Language-agnostic Clean Architecture code generator. One schema, 13 languages, 6 framework presets.

Readme

ClearSchema

Read one schema, generate Clean Architecture layers in the language or framework you want.

ClearSchema is a zero-config CLI that parses a Prisma-style schema and emits strict, SOLID-compliant entity, service, repository, and controller code across 13 target languages and 6 framework presets — all from a single source of truth. Hand-written business logic is preserved across regenerations through a marker-aware merge.

npm install -g clearschema
clearschema ./schema.prisma --lang typescript
clearschema ./schema.prisma --framework nestjs
clearschema ./schema.prisma --framework nestjs,spring-boot,fastapi --out ./services

Why

You have one canonical data model. You want to ship a TypeScript SDK, a Go microservice, a Spring Boot backend, and an iOS Swift client. Today you either hand-write the same entities four times or stitch together four single-purpose generators. ClearSchema is one tool, one schema, one command per output.

It also preserves your custom code: regenerating after a schema change does not clobber the method bodies you wrote inside the marked blocks.


Install

# Global
npm install -g clearschema

# Per-project (recommended for CI reproducibility)
npm install --save-dev clearschema
npx clearschema ./schema.prisma --lang typescript

Node 18.17 or newer.


Quickstart

1. Write a schema

// schema.prisma
model User {
  id        String   @id
  email     String   @unique
  name      String
  age       Int?
  createdAt DateTime
  active    Boolean
}

model Post {
  id        String   @id
  title     String
  body      String
  authorId  String
}

2. Generate

clearschema ./schema.prisma --lang typescript

Output lands in ./ts/:

ts/
├── User.gen.ts            # plain interfaces (overwritten on regen)
├── UserRepository.ts      # interface + in-memory impl (preserved on regen)
├── Post.gen.ts
└── PostRepository.ts

3. Add custom logic

Open UserRepository.ts, find the marker block, drop in your code:

async create(input: UserCreateInput): Promise<User> {
  // //ClearSchema:CustomLogic:Start:create
  const row: User = { ...input, id: crypto.randomUUID() };
  await db.users.insert(row);
  return row;
  // //ClearSchema:CustomLogic:End:create
}

Regenerate after a schema change — your create() body survives.


Three ways to invoke

Zero-config one-shot

clearschema ./schema.prisma --lang ts                       # TypeScript only
clearschema ./schema.prisma --lang ts,dart,go,python        # multi-language
clearschema ./schema.prisma --framework nestjs              # framework preset
clearschema ./schema.prisma --framework spring-boot --out backend/src

Interactive

clearschema
# Auto-detects schema.prisma, prompts for language(s) and output dir.

Committed config (teams)

clearschema init      # writes clearschema.json with your choices
clearschema generate  # uses clearschema.json
clearschema watch     # live dashboard with debounced regeneration

Supported targets

Languages (--lang <name>)

| Language | Aliases | Native type strategy | |---|---|---| | TypeScript | ts, typescript | string, number, boolean, Date | | Dart / Flutter | dart, flutter | String, int, double, DateTime | | Go | go, golang | string, int64, float64, time.Time | | Python | py, python | str, int, float, datetime | | Java | java | String, long, double, Instant | | Kotlin | kt, kotlin | String, Long, Double, Instant | | C# / .NET | cs, csharp, dotnet | string, long, double, DateTime | | Rust | rs, rust | String, i64, f64, chrono::DateTime<Utc> | | Ruby | rb, ruby | String, Integer, Float, Time | | PHP | php | string, int, float, \DateTimeImmutable | | Swift | swift, ios | String, Int64, Double, Date | | Scala | scala | String, Long, Double, java.time.Instant | | Elixir | ex, elixir | String.t(), integer(), float(), DateTime.t() |

Frameworks (--framework <slug>)

Run clearschema frameworks to list everything available.

| Framework | Language | Generates per entity | |---|---|---| | nestjs | TypeScript | entity, dto (class-validator), service, controller, module | | fastapi | Python | Pydantic schema (Create/Update/Read), service, router | | spring-boot | Java | JPA entity, Spring Data repo, @Service, @RestController | | gin-gorm | Go | GORM-tagged struct, service, Gin handler | | aspnet | C# | EF Core entity, service, [ApiController] | | phoenix | Elixir | Ecto schema (changeset), context, controller |

Frameworks auto-derive their language — --framework nestjs already implies TypeScript; you do not need --lang ts.


How it works

ClearSchema is split into four small, modular stages.

Stage 1 — Parser engine

A focused Prisma-flavoured parser deconstructs the schema into a language-neutral Intermediate Representation (IR):

{
  "entities": [
    {
      "entityName": "User",
      "fields": [
        { "name": "id", "type": "String", "isPrimary": true, "isUnique": true, "isNullable": false }
      ]
    }
  ]
}

Errors surface as line-precise diagnostics (line, column, snippet); a single broken row never aborts the generator.

Stage 2 — Polymorphic translation

Each target language ships with a total type-mapping dictionary registered as Handlebars helpers: {{tsType type}}, {{javaType type}}, {{rustType type}}, {{nullableKotlin type isNullable}}, etc. Helpers throw on unknown types rather than silently emitting undefined.

Stage 3 — Custom logic preservation

Every mutable file write goes through a marker-aware merge:

  1. Read existing file (if any).
  2. Extract every block between CustomLogic:Start[:name] and CustomLogic:End[:name].
  3. Render the fresh template.
  4. Splice preserved blocks back into matching markers.
  5. Atomic write via *.tmp + rename.

Marker syntax adapts to the language:

| File extension | Marker style | |---|---| | .ts .dart .go .java .kt .cs .rs .swift .php .scala | // //ClearSchema:CustomLogic:Start[:name] | | .py .rb .ex .exs .sh | # #ClearSchema:CustomLogic:Start[:name] |

Note: the bundled templates currently emit the marker token as SchemaSync:CustomLogic:Start for historical compatibility — both forms are recognised by the merge engine.

Templates expose multiple named blocks (create, update, findById, …) so your edits to one method never collide with another.

Stage 4 — Watcher + dashboard

clearschema watch uses chokidar with a 300 ms debounce to bundle rapid IDE saves, then renders a locked terminal dashboard showing:

  • Compilation time (Took 142ms)
  • A tree of generated files grouped by target
  • Count of preserved custom-logic blocks per file
  • Diagnostics with line:column and snippet

Configuration file

For team workflows, commit a clearschema.json at the project root:

{
  "schema": "schema.prisma",
  "templatesRoot": "templates",
  "targets": [
    {
      "name": "typescript",
      "language": "typescript",
      "outputDir": "src/generated/ts",
      "templates": [
        { "template": "typescript/entity.hbs",     "outputPattern": "{{entity}}.gen.ts",       "overwrite": true },
        { "template": "typescript/repository.hbs", "outputPattern": "{{entity}}Repository.ts" }
      ]
    },
    {
      "name": "spring-backend",
      "language": "java",
      "outputDir": "backend/src/main/java",
      "templates": [
        { "template": "java/spring-boot/entity.hbs",     "outputPattern": "domain/{{entity}}.java",                "overwrite": true },
        { "template": "java/spring-boot/repository.hbs", "outputPattern": "repository/{{entity}}Repository.java",  "overwrite": true },
        { "template": "java/spring-boot/service.hbs",    "outputPattern": "service/{{entity}}Service.java" },
        { "template": "java/spring-boot/controller.hbs", "outputPattern": "controller/{{entity}}Controller.java" }
      ]
    }
  ]
}

The templatesRoot field is optional — omit it to use ClearSchema's bundled templates. Set overwrite: true for boilerplate files that should be rewritten on every run; omit it (default) to enable preservation.


Writing custom templates

Templates are Handlebars with these helpers registered globally:

Type helpers — one per language: {{tsType}} {{dartType}} {{goType}} {{pyType}} {{javaType}} {{kotlinType}} {{csType}} {{rustType}} {{rubyType}} {{phpType}} {{swiftType}} {{scalaType}} {{elixirType}}

Nullable wrappers — wrap the native type in the idiomatic optional shape: {{nullableTs type isNullable}}T | null · {{nullableDart type isNullable}}T? · {{nullableJava type isNullable}}Optional<T> · {{nullableRust type isNullable}}Option<T> · {{nullableScala type isNullable}}Option[T] · {{nullableElixir type isNullable}}T | nil

String cases: {{pascalCase x}} {{camelCase x}} {{snakeCase x}}

Subexpression conditionals: {{#if (eq type "String")}}…{{/if}}

Context available in every template: entityName, entityLower, entitySnake, entityKebab, fields[] (each with name, type, nativeType, isPrimary, isUnique, isNullable), entity, target.


CLI reference

| Command | Description | |---|---| | clearschema | Interactive flow — auto-detects schema, prompts for languages and output dir | | clearschema <schema> --lang <list> | Zero-config language generation | | clearschema <schema> --framework <list> | Zero-config framework generation | | clearschema init | Scaffold a clearschema.json | | clearschema generate | Render once using clearschema.json | | clearschema watch | Live dashboard with debounced regeneration | | clearschema frameworks | List every available framework preset | | clearschema --help | Top-level help | | clearschema <command> --help | Per-command help |

| Flag | Description | |---|---| | -l, --lang <list> | Comma-separated language slugs | | -f, --framework <list> | Comma-separated framework slugs (implies --lang) | | -o, --out <dir> | Output base directory (default: current directory) | | -c, --config <path> | Path to a clearschema.json |


License

MIT © Osama Riyad