FastCRUD CLI
The FastCRUD CLI connects to your project, reads the introspected database schema, and generates typed models and a ready-to-use CRUD client in your language of choice.
Installation
From source (requires Go 1.21+)
git clone https://github.com/Skyvko6607/fast-crud-cli.git
cd fast-crud-cli
go build -o fastcrud-cli .
Move the binary somewhere on your PATH:
# Linux / macOS
mv fastcrud-cli /usr/local/bin/
# Windows (PowerShell)
Move-Item fastcrud-cli.exe C:\Users\<you>\bin\
Quick Start
Generate a TypeScript client for your project in three commands:
# 1. Generate the client
fastcrud-cli --key YOUR_ACCESS_KEY_ID --lang typescript --output ./src/api
# 2. Check the output
ls ./src/api/
# models.ts client.ts
# 3. Use it in your code
import { FastCrudClient } from "./api/client";
const api = new FastCrudClient("https://api.fastcrud.dev", "YOUR_ACCESS_KEY_ID");
await api.authenticate();
const users = await api.queryUsers("age.gt.18", 50);
console.log(users);
Usage
fastcrud-cli --key <access-key-id> --lang <language> [--output <dir>] [--url <base-url>]
Flags
| Flag | Required | Default | Description |
|---|---|---|---|
--key | Yes | — | Your project's access key ID (UUID). Found in the dashboard under your project settings. |
--lang | Yes | — | Target language for code generation. See Supported Languages. |
--output | No | ./generated | Directory where generated files are written. Created automatically if it doesn't exist. |
--url | No | https://api.fastcrud.dev | Base URL of the FastCRUD API. Override this if you're running a self-hosted instance. |
Supported Languages
--lang value | Aliases | Generated files |
|---|---|---|
go | golang | models.go, client.go |
csharp | c#, cs | Models.cs, FastCrudClient.cs |
typescript | ts, node, nodejs | models.ts, client.ts |
java | — | {Table}.java (one per table), FastCrudClient.java |
What Gets Generated
The CLI generates two things for every language:
1. Typed models
One struct / class / interface per database table. Fields are mapped from your database column types to the target language's native types.
Type mapping:
| Database type | Go | C# | TypeScript | Java |
|---|---|---|---|---|
integer, int, smallint, bigint | int | int | number | int |
float, numeric, decimal, double, real | float64 | double | number | double |
boolean | bool | bool | boolean | boolean |
timestamp, date, time | string | DateTime | string | String |
Everything else (text, varchar, uuid, etc.) | string | string | string | String |
2. CRUD client
A client class / struct with:
Authenticate()— exchanges your access key for a Bearer tokenQuery{Table}(filter, limit, offset)—GET /crud/:tablewith filter, paginationInsert{Table}(rows)—POST /crud/:tableUpdate{Table}(data, filter)—PUT /crud/:tableDelete{Table}(filter)—DELETE /crud/:table
Methods are generated for every table in your database. The client handles authentication headers, JSON serialization, query parameter encoding, and error responses.
Examples
Go
fastcrud-cli --key 550e8400-e29b-41d4-a716-446655440000 --lang go --output ./pkg/fastcrud
package main
import (
"fmt"
"log"
"your-project/pkg/fastcrud"
)
func main() {
client := fastcrud.NewClient(
"https://api.fastcrud.dev",
"550e8400-e29b-41d4-a716-446655440000",
)
if err := client.Authenticate(); err != nil {
log.Fatal(err)
}
// Query users with a filter
users, err := client.QueryUsers("status.eq.active", 100, 0)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Found %d users\n", len(users))
// Insert a new order
inserted, err := client.InsertOrders([]fastcrud.Order{
{UserId: 42, Total: "99.99", Status: "pending"},
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Inserted %d row(s)\n", inserted)
}
C#
fastcrud-cli --key 550e8400-e29b-41d4-a716-446655440000 --lang csharp --output ./FastCrud
using FastCrud;
var client = new FastCrudClient(
"https://api.fastcrud.dev",
"550e8400-e29b-41d4-a716-446655440000"
);
await client.AuthenticateAsync();
// Query with filter and pagination
var users = await client.QueryUsersAsync(
filter: "age.gt.18 AND status.eq.active",
limit: 50
);
// Update rows matching a filter
var affected = await client.UpdateUsersAsync(
new User { Status = "inactive" },
filter: "last_login.lt.2024-01-01"
);
Console.WriteLine($"Updated {affected} row(s)");
TypeScript / Node
fastcrud-cli --key 550e8400-e29b-41d4-a716-446655440000 --lang typescript --output ./src/api
import { FastCrudClient } from "./api/client";
const api = new FastCrudClient(
"https://api.fastcrud.dev",
"550e8400-e29b-41d4-a716-446655440000"
);
await api.authenticate();
// Fetch active users
const users = await api.queryUsers("status.eq.active", 100);
// Delete expired sessions
const deleted = await api.deleteSessions("expires_at.lt.2024-01-01");
console.log(`Cleaned up ${deleted} session(s)`);
Java
fastcrud-cli --key 550e8400-e29b-41d4-a716-446655440000 --lang java --output ./src/main/java/fastcrud
import fastcrud.FastCrudClient;
import fastcrud.User;
public class Main {
public static void main(String[] args) throws Exception {
var client = new FastCrudClient(
"https://api.fastcrud.dev",
"550e8400-e29b-41d4-a716-446655440000"
);
client.authenticate();
// Query users
var users = client.queryUsers("age.gt.18", 100, 0);
System.out.println("Found " + users.size() + " users");
// Insert rows
var rows = List.of(new User());
int inserted = client.insertUsers(rows);
System.out.println("Inserted " + inserted + " row(s)");
}
}
Note: The Java client depends on Gson for JSON serialization. Add it to your
pom.xmlorbuild.gradle.
How It Works
When you run the CLI, it performs three steps:
1. Authenticate — sends POST /authenticate/crud/:accessKeyID to get a short-lived Bearer token.
2. Fetch schema — sends GET /schema with the Bearer token. The API returns your project's introspected tables and columns, including database-native data types.
3. Generate code — maps each table to a model class and builds a client with typed CRUD methods. Files are written to the output directory.
The generated client is standalone — it has no dependency on the CLI or any FastCRUD SDK. It uses only standard HTTP libraries for the target language.
Filter Syntax
The generated client methods accept a filter string parameter. Filters follow the same syntax used by the REST API:
column.operator.value
Operators: eq, neq, gt, gte, lt, lte, like
Combining conditions:
age.gt.18 AND status.eq.active
age.gt.18 OR role.eq.admin
See the full Filter Syntax documentation for details.
Regenerating After Schema Changes
If you add tables or columns to your database, the schema is re-introspected automatically (cache TTL is 10 minutes). Run the CLI again to regenerate:
fastcrud-cli --key YOUR_KEY --lang go --output ./pkg/fastcrud
The CLI overwrites existing files in the output directory. If you've made manual edits to the generated code, back them up first or use a wrapper layer instead of editing the generated files directly.
Troubleshooting
| Problem | Cause | Fix |
|---|---|---|
authentication failed (401) | Invalid or expired access key ID | Check the UUID in your dashboard. Access keys don't expire, but they can be revoked. |
schema fetch failed (401) | Token issue | The token is valid for 24 hours. If you see this immediately after auth, check your --url flag. |
No tables found | Database not introspected | Add a connection in your project dashboard. The schema is introspected automatically when a connection is registered. |
0 tables, but database has data | Wrong project | Verify you're using the access key for the correct project. Each project has its own key. |