Wrm 3.1.0
See the version list below for details.
dotnet tool install --global Wrm --version 3.1.0
dotnet new tool-manifest
dotnet tool install --local Wrm --version 3.1.0
#tool dotnet:?package=Wrm&version=3.1.0
nuke :add-package Wrm --version 3.1.0
WormScript (WRM)
Version: 2.9.5 Framework: .NET 9.0 License: Furniss Software (c) 2026
WRM pronounced "Worm", is a command line code generation tool that transforms database schemas into complete full-stack applications. Using a database-first approach, WormScript automatically generates RESTful APIs, data models, CRUD operations, and modern web components from your database structure.
Basic Usage
- Initialize a new project with
wrm init MyProject react. - Edit the generated
.wrm/MyProject.wrmwith your connection string. - Run
wrm build. - Sit back and watch your complete application being generated!
Table of Contents
- Features
- Supported Technologies
- Installation
- Quick Start
- Usage
- Project Structure
- Generated Output
- Configuration
- Database Support
- Examples
- Contributing
Additional Documentation:
- Architecture - Internal architecture and build process
- Template System - Template markers and available templates
- Features - Feature system details
Features
- Database-First Development - Generate entire applications from existing database schemas
- Multi-Database Support - PostgreSQL (primary), MySQL templates available
- Full-Stack Generation - Backend APIs + Frontend components in one command
- Three-Tier Architecture - Separate Data, API, and Web projects
- RESTful API Generation - Complete CRUD controllers with filtering and custom queries
- Modern Web Components - React, CoreUI support
- Dapper ORM Integration - Lightweight, performant repositories with multi-mapping
- Smart Code Generation - Automatic finder methods based on foreign keys and column annotations
- Tree Model Support - Hierarchical models with nested sub-objects
- Soft/Hard Delete Support - Configurable deletion strategies
- Multi-Tenancy Ready - Organization-based data isolation
- GraphQL Support - Optional GraphQL API layer
- Model Context Protocol (MCP) - AI integration capabilities
- Docker Support - Container configurations for PostgreSQL and MySQL
- Swagger/OpenAPI - Automatic API documentation
- Modular Features - Plugin-style feature system with dependency management
- Paged Data - Built-in pagination support for API endpoints
Future Features
- SQL Server Support
- Azure Cosmos DB Support
- Vue.js Frontend Support
- Angular Frontend Support
- Enhanced Test Data Generation
Supported Technologies
Backend
- .NET 8.0/9.0 - Core framework
- ASP.NET Core - Web API
- Entity Framework Core - Schema reading
- Dapper - Generated CRUD operations with multi-mapping
- Serilog - Logging
Frontend
- React - Modern UI library
- React JSX - Advanced component patterns
- CoreUI - Bootstrap-based admin templates
Databases
- PostgreSQL (primary, fully supported)
- MySQL (templates available)
Docker
- Docker - Containerization of database + API
- Docker Compose - Multi-container orchestration
Installation
Install WormScript as a global .NET tool:
dotnet tool install --global Wrm
Verify installation:
wrm help
Quick Start
1. Initialize a New Project
Choose the name of your project wisely, it will be used throughout the generated code. No spaces or underlines. Case sensitive.
wrm init MyProject react
cd MyProject
This creates:
.wrm/MyProject.wrm- Build script.wrm/MyProject.sql- Database schema
2. Define Your Database Schema
Edit .wrm/MyProject.sql:
-- STAR-SYSTEMS
DROP TABLE IF EXISTS star_systems;
CREATE TABLE star_systems(
star_system_id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
system_name VARCHAR(255) NOT NULL
);
-- STARS - Stars that belong in a star-system
DROP TABLE IF EXISTS stars;
CREATE TABLE stars(
star_id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
star_system_id INTEGER,
star_name VARCHAR(255) NOT NULL
);
-- PLANETS
DROP TABLE IF EXISTS planets;
CREATE TABLE planets(
planet_id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
star_id INTEGER,
planet_name VARCHAR(255) NOT NULL,
planet_code VARCHAR(25) NOT NULL
);
3. Create and Run Your Database
Create a PostgreSQL database named MyProject and run the SQL script to set up the schema.
Optionally don't use the DATABASE RUN command in the Wrm script and rely on an existing database.
4. Configure Your Wrm Script
Edit .wrm/MyProject.wrm:
CREATE PROJECT MyProject
DOC SWAGGER
USE SOFT DELETE
CONNECTION POSTGRES 'Host=localhost:5432;Username=postgres;Password=postgres;Database=MyProject'
DATABASE RUN '.wrm/MyProject.sql'
CREATE TESTDATA IFEMPTY USECASES 10
CREATE MODELS
CREATE API CONTROLLERS
CREATE API SERVICE
CREATE COMPONENTS
5. Build Your Project
wrm build
Your complete application is now generated!
Usage
Commands
wrm <init|build|test|list|help> [options]
init- Initialize a new projectbuild- Build the projecttest- Test database connectivitylist- List project components for debugging
wrm init [ProjectName] [WebComponentType]
Creates a new WormScript project structure. A base set of components is created for each entity table in the required web framework form.
wrm init MyProject react # React components
wrm init MyProject coreui # CoreUI components
wrm build
Executes the .wrm script and generates all code.
wrm build
wrm test connection
Tests database connectivity.
wrm test connection
wrm list [OPTION]
Lists project components for debugging.
Options:
ENTITIES- All entity tablesMODELS- Generated modelsPORTS- API ports configurationTEMPLATES- Available templatesTABLES- Database tablesFEATURES- Enabled featuresCONFIG- Configuration settingsCONNECTION- Database connection info (masked)
wrm list tables
wrm list features
wrm database
Shows database information and connection details.
wrm database
wrm help [command]
Shows help information.
wrm help
wrm help init
wrm help build
WRM Script Syntax
WormScript uses a simple, declarative syntax:
Basic Structure
-- Comments start with -- or //
CREATE PROJECT ProjectName
DOC SWAGGER -- Enable Swagger docs
USE SOFT DELETE -- Use soft delete (is_deleted column)
-- USE HARD DELETE -- Alternative: permanent deletion
CONNECTION POSTGRES 'Host=localhost;Database=mydb;Username=user;Password=pass'
DATABASE RUN '.wrm/schema.sql'
CREATE MODELS -- Generate model classes
CREATE API CONTROLLERS -- Generate API controllers
CREATE API SERVICE -- Generate microservice code
CREATE COMPONENTS -- Generate web components
CREATE TESTDATA IFEMPTY USECASES 10 -- Generate test data
Commands
| Command | Description |
|---|---|
CREATE PROJECT <name> |
Initialize project configuration (required first) |
DATABASE RUN '<filepath>' |
Execute SQL script to create/update schema |
CREATE MODELS |
Generate C# model classes from database tables |
CREATE MODEL <tablename> |
Generate single model |
CREATE API SERVICE |
Generate all API controllers |
CREATE COMPONENTS |
Generate web UI components |
CREATE LOOKUP |
Generate lookup/finder methods |
CREATE TESTDATA [options] |
Generate test data |
CREATE TESTTABLE [name] |
Create test table with all data types |
Connection Strings
-- PostgreSQL
CONNECTION POSTGRES 'Host=localhost:5432;Database=mydb;Username=user;Password=pass'
-- MySQL
CONNECTION MYSQL 'Server=localhost;Database=mydb;User=user;Password=pass'
Features System
WormScript includes a modular feature system. Enable features with the FEATURE sub command:
CREATE PROJECT <name>
FEATURE BASE -- Base functionality (required by others)
FEATURE AUTH -- Authentication/Authorization (JWT)
FEATURE ORGANISATIONS -- Multi-tenancy support with hierarchical organizations
FEATURE USERS -- User management tables
FEATURE FILEHANDLING -- File attachment support
FEATURE GRAPHQL -- GraphQL API layer
FEATURE ENTITIES -- Entity configuration framework
FEATURE MCP; -- Model Context Protocol (AI integration)
FEATURE RPC -- Remote Procedure Call support
WARNING: The current implementation of FEATURES will DROP EVERYTHING in the public schema and recreate the public schema with nothing in it. Use with caution on existing databases.
See Features.md for full list and descriptions.
Feature Dependencies:
Features automatically enable their dependencies. For example:
ORGANISATIONSrequiresBASEAUTHrequiresBASEandUSERSFILEHANDLINGrequiresBASE
Project Structure
After running wrm init MyProject react and wrm build, you get:
MyProject/
├── .wrm/
│ ├── MyProject.wrm # Build script
│ └── MyProject.sql # Database schema
│
├── MyProjectData/ # Data Access Layer
│ ├── Config/
│ │ └── DbConnectionConfig.cs
│ ├── Database/
│ │ └── BaseRepository.cs # Base repository class
│ ├── Models/
│ │ ├── IDatabaseModel.cs # Model interface
│ │ ├── UserDbModel.cs # Entity models
│ │ ├── UserFlatModel.cs # Flat/joined models
│ │ └── UserTreeModel.cs # Hierarchical models
│ ├── Repositories/
│ │ ├── UserRepository.cs # Dapper CRUD operations
│ │ └── ...
│ └── MyProjectData.csproj
│
├── MyProjectService/ # API Service Layer
│ ├── Controllers/
│ │ ├── UserController.cs
│ │ └── ...
│ ├── GraphQL/ # (if GRAPHQL feature enabled)
│ │ ├── UserQLQuery.cs
│ │ └── UserQLMutation.cs
│ ├── MCP/ # (if MCP feature enabled)
│ │ └── UserMCPController.cs
│ ├── Security/ # (if AUTH feature enabled)
│ │ ├── AuthController.cs
│ │ └── JwtTokenService.cs
│ ├── Config/
│ ├── Logging/
│ ├── Program.cs
│ ├── appsettings.json
│ └── MyProjectService.csproj
│
├── MyProjectReact/ # Web UI (React)
│ ├── src/
│ │ ├── components/
│ │ │ └── project/
│ │ │ └── User/
│ │ │ ├── UserApi.js
│ │ │ ├── UserForm.jsx
│ │ │ ├── UserTable.jsx
│ │ │ ├── UserCard.jsx
│ │ │ └── UserDropdown.jsx
│ │ ├── routes/
│ │ └── layouts/
│ └── package.json
│
├── MyProject.Tests/ # Unit Tests
│ ├── UserDbFullTests.cs
│ ├── UserDbQuickTests.cs
│ └── MyProject.Tests.csproj
│
├── docker/ # Docker Configurations
│ ├── docker-compose.yml
│ ├── docker-compose.prod.yml
│ └── Dockerfile
│
└── MyProject.sln # Solution file
Generated Output
API Controllers
For each table, WormScript generates:
UserController.cs:
[ApiController]
[Route("api/[controller]")]
public class UserController : ControllerBase
{
private readonly UserRepository _repository;
[HttpGet]
public async Task<IActionResult> GetAll() { ... }
[HttpGet("paged")]
public async Task<IActionResult> GetAllPaged(int page, int pageSize) { ... }
[HttpGet("{id}")]
public async Task<IActionResult> GetById(int id) { ... }
[HttpPost]
public async Task<IActionResult> Create([FromBody] UserDbModel model) { ... }
[HttpPut("{id}")]
public async Task<IActionResult> Update(int id, [FromBody] UserDbModel model) { ... }
[HttpDelete("{id}")]
public async Task<IActionResult> Delete(int id) { ... }
// Custom finder methods based on column annotations
[HttpGet("email/{email}")]
public async Task<IActionResult> FindByEmail(string email) { ... }
}
Data Models
WormScript generates three types of models:
Standard Models (UserDbModel.cs):
public class UserDbModel : IDatabaseModel
{
public int UserId { get; set; }
public DateTime CreatedAt { get; set; }
public int? CreatedBy { get; set; }
public DateTime? UpdatedAt { get; set; }
public int? UpdatedBy { get; set; }
public bool IsDeleted { get; set; }
public string Username { get; set; }
public string Email { get; set; }
}
Flat Models (UserFlatModel.cs): Read-only models for joined queries across tables.
Tree Models (UserTreeModel.cs): Hierarchical models with nested sub-objects for parent-child relationships.
Dapper Repositories
UserRepository.cs:
public class UserRepository : BaseRepository
{
public async Task<UserDbModel> GetById(int id) { ... }
public async Task<IEnumerable<UserDbModel>> GetAll() { ... }
public async Task<PagedResult<UserDbModel>> GetAllPaged(int page, int pageSize) { ... }
public async Task<int> Create(UserDbModel model) { ... }
public async Task<bool> Update(UserDbModel model) { ... }
public async Task<bool> Delete(int id) { ... }
public async Task<bool> Upsert(UserDbModel model) { ... }
// Custom finders based on ## annotations
public async Task<UserDbModel> FindByEmail(string email) { ... }
}
Web Components
UserApi.js:
const API_BASE = '/api/user';
export const UserApi = {
getAll: () => fetch(API_BASE),
getById: (id) => fetch(`${API_BASE}/${id}`),
create: (data) => fetch(API_BASE, { method: 'POST', body: JSON.stringify(data) }),
update: (id, data) => fetch(`${API_BASE}/${id}`, { method: 'PUT', body: JSON.stringify(data) }),
delete: (id) => fetch(`${API_BASE}/${id}`, { method: 'DELETE' }),
};
Configuration
Database Annotations
Use SQL comments to control code generation:
CREATE TABLE users(
user_id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
email VARCHAR(255) NOT NULL,
username VARCHAR(255) NOT NULL,
organization_id INTEGER, -- '_id' allows for automatic foreign key detection
nickname VARCHAR(100)
);
COMMENT ON COLUMN user.email IS '##'; -- Creates FindByEmail() method in API
COMMENT ON COLUMN user.username IS '##'; -- Creates FindByUsername() method in API
COMMENT ON COLUMN user.nickname IS 'HIDE'; -- field is hidden from API and UI
COMMENT ON TABLE users IS 'PAGED'; -- API must use the skip & take parameters for paging
The ## fieldname annotation tells WormScript to generate a finder method for that column.
Special Comment Annotations
FindBy
Creation of a lookup/finder method for the field. Add ',PAGED' to indicate the method should return paged results.
COMMENT ON COLUMN table.field IS '##'
Name
Marks the field as a "name" field for display purposes.
COMMENT ON COLUMN table.field IS 'NAME'
Every table should have one field as the designated name field. If one is not specified, WormScript will look for common candidates like name, title, or description.
This may be used in dropdowns and other UI elements. It doesn't have to be unique.
Hide
Hides the field from API and UI.
COMMENT ON COLUMN table.field IS 'HIDE'
Enumeration tables
Defines the table as an enumeration.
COMMENT ON TABLE table IS 'ENUM'
PAGED tables
Defines the table as an enumeration.
COMMENT ON TABLE table IS 'ENUM'
Column Naming Conventions
Columns with certain names are treated specially for UI generation:
| Column Name Contains | UX Effect |
|---|---|
| latitude | UX builds data-entry and validation relevant to a latitude or longitude |
| longitude | UX builds data-entry and validation relevant to a latitude or longitude |
| Email UX and validation | |
| password | Password UX and validation |
| enum | Builds radio selection based on the referenced ENUM TABLE |
| w3w | UX data-entry and handling for What3Words |
Database Support
PostgreSQL (Recommended)
CREATE TABLE users(
user_id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
username VARCHAR(255) NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
Features:
GENERATED ALWAYS AS IDENTITYfor auto-incrementLIKEclause for table inheritanceTIMESTAMPTZfor timestamps- JSON/JSONB support
- Schema support
MySQL (Partial support)
CREATE TABLE users(
user_id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Examples
Complete Example
1. Create project:
wrm init BlogApp react
cd BlogApp
2. Define schema (.wrm/BlogApp.sql):
DROP TABLE IF EXISTS posts;
CREATE TABLE posts(
post_id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
title VARCHAR(255) NOT NULL,
content TEXT,
author_id INTEGER NOT NULL,
-- ## author_id
published_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
is_deleted BOOLEAN NOT NULL DEFAULT FALSE
);
DROP TABLE IF EXISTS comments;
CREATE TABLE comments(
comment_id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
post_id INTEGER NOT NULL,
-- ## post_id
content TEXT NOT NULL,
author_name VARCHAR(255),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
3. Configure build (.wrm/BlogApp.wrm):
CREATE PROJECT BlogApp
DOC SWAGGER
USE SOFT DELETE
CONNECTION POSTGRES 'Host=localhost:5432;Database=blogapp;Username=postgres;Password=postgres'
FEATURE BASE
FEATURE USERS
DATABASE RUN '.wrm/BlogApp.sql'
CREATE TESTDATA IFEMPTY USECASES 20
CREATE MODELS
CREATE API SERVICE
CREATE COMPONENTS
4. Build:
wrm build
5. Run API:
cd BlogAppService
dotnet run
Your API is now running with:
GET /api/post- Get all postsGET /api/post/paged?page=1&pageSize=10- Get paged postsGET /api/post/{id}- Get post by IDGET /api/post/author/{authorId}- Get posts by authorPOST /api/post- Create postPUT /api/post/{id}- Update postDELETE /api/post/{id}- Soft delete postGET /api/comment/post/{postId}- Get comments by post
Naming Conventions
WormScript intelligently converts between naming conventions:
| Context | Convention | Example |
|---|---|---|
| Database | snake_case | user_profile |
| C# Classes | PascalCase | UserProfile |
| C# Properties | PascalCase | UserProfile |
| JavaScript | camelCase | userProfile |
| UI Labels | Spaced | User Profile |
| Singular Forms | Auto | users → User |
Dependencies
Runtime Requirements
- .NET 8.0 or 9.0 SDK/Runtime
- Database server (PostgreSQL or MySQL)
Generated Project Dependencies
The generated projects include:
- ASP.NET Core 8.0/9.0
- Dapper 2.1.66
- Npgsql (for PostgreSQL)
- Serilog (logging)
- Swagger/OpenAPI
- Optional: JWT Bearer, Entity Framework Core
Contributing
WormScript is developed by Furniss Software. For issues, feature requests, or contributions:
- Check existing issues
- Follow the project's coding standards
- Test generated code thoroughly
- Submit pull requests with clear descriptions
License
Copyright (c) 2025 Furniss Software. All rights reserved.
Support
- Documentation: Check
.wrm/folder examples after runningwrm init - Issues: Report bugs via the project repository
- Database Connection: Use
wrm test connectionto diagnose connectivity - Debugging: Use
wrm listcommands to inspect project state
Changelog
v2.8.0
- Refactored ComponentWriter to RepositoryWriter for better semantics
- Added Tree model support with Dapper multi-mapping
- Improved nested block handling in conditional processing
- Performance improvements in comment skipping (O(n) vs O(n^2))
v2.2.0
- Docker Compose enhancements and fixes
v2.1.2
- Bug fix in JWT security
v2.1.1
- Numerous bug fixes
- AUTH feature
- Paged data support
v2.0.0
- Model Context Protocol (MCP) integration
- Enhanced API unit test templates
- Improved database namespace organization
- Updated comment syntax (
//WRM_prefix)
Happy Coding with WormScript!
Transform your database into a complete application in minutes.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
This package has no dependencies.
| Version | Downloads | Last Updated | |
|---|---|---|---|
| 3.3.4 | 85 | 4/13/2026 | |
| 3.3.2 | 101 | 3/5/2026 | |
| 3.3.1 | 85 | 3/5/2026 | |
| 3.3.0 | 91 | 2/27/2026 | |
| 3.2.2 | 101 | 2/15/2026 | |
| 3.2.1 | 85 | 2/15/2026 | |
| 3.2.0 | 91 | 2/15/2026 | |
| 3.1.1 | 124 | 2/3/2026 | |
| 3.1.0 | 95 | 2/3/2026 | |
| 3.0.0 | 109 | 1/22/2026 | |
| 2.9.4 | 98 | 1/22/2026 | |
| 2.9.2 | 99 | 1/22/2026 | |
| 2.9.0 | 102 | 1/21/2026 | |
| 2.8.0 | 117 | 1/12/2026 | |
| 2.7.0 | 686 | 12/1/2025 | |
| 2.6.1 | 109 | 1/12/2026 | |
| 2.6.0 | 682 | 12/1/2025 | |
| 2.5.0 | 681 | 12/1/2025 | |
| 2.3.0 | 200 | 11/24/2025 | |
| 2.2.0 | 421 | 11/20/2025 |