forja v1.0.0

[ v1.0.0 ] Hexagonal projects, generated

Architecture first.
Features next.

forja generates a TypeScript monorepo with Next.js and Expo, or a Spring Boot or Quarkus API with a Next.js web app. The hexagonal architecture is in place, sign-in works, and every test is green on the first run. Then forja add grows it one use case at a time, inside the rules.

Get started Java backends

Three commands
npm install -g @rsaglobaltech/forja
forja init shop             # the wizard
forja add usecase orders/PlaceOrder
3
backends: Node, Spring Boot, Quarkus
2
apps on one core: Next.js 16 and Expo SDK 57
1
command from an empty folder to green tests
0
runtime dependencies on forja in what it writes

Plain code you ownMITEvery path generated, installed, tested, built and driven in a browser before a release

A template is where a project starts. The rules are what keep it standing.

A starter template gets copied once. A month later the first shortcut lands: a page that queries the database, a use case that imports React. Nothing fails, so nothing stops it.

forja generates the rules with the code. On Java, ArchUnit fails the build when the domain reaches for Spring or one module uses another's infrastructure. On Node, forja doctor catches a UI import in the core. And forja add writes each new use case, entity and port where those rules expect it, already wired and already tested.

The architecture, and every rule it keeps →

What you get

Two shapes. The same hexagon.

forja init shop · Node
shop/
├── apps/
│   ├── web/        Next.js 16: pages, server actions, auth API
│   └── mobile/     Expo SDK 57 + NativeWind
├── packages/
│   ├── core/       the hexagon, shared by both apps
│   │   └── src/
│   │       ├── domain/          User, Email, Password
│   │       ├── application/     Register, Login, Logout…
│   │       ├── ports/           IUserRepository, IMailer…
│   │       └── infrastructure/  Drizzle, bcrypt, container.ts
│   └── shared/     design tokens
├── docker-compose.yml  PostgreSQL
└── forja.config.json
forja init shop --backend spring
shop/
├── apps/
│   ├── api/        Spring Boot 4 (or Quarkus 3)
│   │   └── src/main/java/com/shop/
│   │       ├── tasks/
│   │       │   ├── domain/          Task, TaskTitle
│   │       │   ├── application/     CreateTask… + port/
│   │       │   └── infrastructure/  web, persistence, config
│   │       └── shared/
│   └── web/        Next.js 16, signs in with Keycloak
├── infra/keycloak/ a realm with demo / demo
├── docker-compose.yml  PostgreSQL + Keycloak
└── forja.config.json

The day after

One command per feature.

Run forja add anywhere inside the project. It reads forja.config.json, writes the class and its test, wires it into the composition root, and overwrites nothing. With Specgate in the project, the requirement comes with it.

forja add and forja doctor →

Terminal
$ forja add usecase orders/PlaceOrder
┌  forja add usecase
◆  created  packages/core/src/application/orders/PlaceOrderUseCase.ts
◆  created  packages/core/tests/unit/orders/PlaceOrderUseCase.test.ts
●  updated  packages/core/src/index.ts
●  updated  packages/core/src/infrastructure/config/container.ts
◇  REQ-003 · Place order
│  scenario to write: features/place-order.feature
└  Next: write the scenario, make the test prove it (npm test),
   then npx specgate done REQ-003
Terminal
$ forja doctor
┌  forja doctor · shop
◆  Node.js        v24.14.0
◆  Docker         engine 29.5.3
▲  env (root)     no .env yet: the defaults in the code apply
│  cp .env.example .env
◆  React          one version everywhere (19.2.3)
■  core imports   packages/core/src/domain/entities/Order.ts:31 imports react
│  Move that code to apps/* or infrastructure/, and reach it through a port
└  1 to fix, 1 to look at

On the first run

What works before you write a line.

Sign-in, end to end

On Node: register, sign in, sessions in an httpOnly cookie, password reset. On Java: OAuth2 with Keycloak, the API as a resource server, and a realm with a demo user.

Tests from the first commit

vitest for the core's use cases; JUnit, Testcontainers and a real PostgreSQL for the API. Add --tests e2e-web and Playwright drives the sign-in in a browser.

Rules that are checked

ArchUnit on the API: a pure domain, no framework in the application, ports as interfaces, no cycles. forja doctor keeps the Node core free of UI imports.

Web and mobile, one core

Next.js and Expo import the same packages/core. One React version for both, the one Expo pins, so hooks never meet two copies.

Specgate, adopted

With the specgate extra, the project starts with a brief to fill in and a gate that runs your tests. Each use case you add names its requirement.

Plain code, no lock-in

What forja writes is yours: no runtime package, no generated folder to leave alone. Delete forja.config.json and the project still builds.

forja + Specgate

The use case and its requirement, in one step.

forja builds the structure. Specgate decides when a requirement is done: a scenario, a test that names it, and a suite that passes. forja add usecase creates the requirement, names it in the test, and regenerates the traceability matrix.

How the two work together →

packages/core/tests/unit/orders/PlaceOrderUseCase.test.ts
import { describe, expect, it } from "vitest";
import { PlaceOrderUseCase } from "../../../src/application/orders/PlaceOrderUseCase.js";

describe("REQ-003 Place order", () => {
  it("runs", async () => {
    const result = await new PlaceOrderUseCase().execute();
    expect(result.ok).toBe(true);
  });

  it.todo("proves the scenario in features/place-order.feature");
});

Questions people ask first.

Does forja stay in my project?

Only as forja.config.json, which forja add and forja doctor read. The generated code has no dependency on forja; delete the file and the project still builds and tests.

Can I run forja add on a project forja did not generate?

It needs the layout forja generates and a forja.config.json that describes it. On another layout it stops with an error before it writes anything.

Which combinations are supported?

Node with web, mobile or both; Spring Boot or Quarkus with a web app or as an API only. Mobile with a Java backend is not supported yet, and the CLI says so instead of generating half a project. See the command line reference.

Does it need GitHub Actions?

No. The ci extra writes a workflow if you want one; it is off by default. Everything forja generates runs locally with npm test.

Start at the first feature.

bash
npx @rsaglobaltech/forja init

Get started Command line