Stop writingredundant code.
A spec-driven code generator that keeps your codebase consistent and up-to-date, so you can focus writing the code that sets your app apart.
Keep your codebase consistent
Maintaining a consistent codebase is hard. But it is the key to efficiency and scalability. Naming conventions, design patterns and coding standards are a big part of this. ZappJS ensures uniformity across your entire project.
models: post: attributes: title: required: true type: string unique: true content: required: true type: string user: attributes: name: type: string
import { ColumnType, Generated, sql } from 'kysely' import { db } from '@/lib/db' export interface PostsTable { id: Generated<number> title: string content: string createdAt: ColumnType<Date, string | undefined, never> } export const createPostsTable = async () => { await db.schema .createTable('posts') .ifNotExists() .addColumn('id', 'serial', (cb) => cb.primaryKey()) .addColumn('title', 'varchar(255)', (cb) => cb.notNull().unique()) .addColumn('content', 'varchar(255)', (cb) => cb.notNull()) .addColumn('createdAt', sql`timestamp with time zone`, (cb) => cb.defaultTo(sql`current_timestamp`) ) .execute() }
import { ColumnType, Generated, sql } from 'kysely' import { db } from '@/lib/db' export interface UsersTable { id: Generated<number> name?: string createdAt: ColumnType<Date, string | undefined, never> } export const createUsersTable = async () => { await db.schema .createTable('users') .ifNotExists() .addColumn('id', 'serial', (cb) => cb.primaryKey()) .addColumn('name', 'varchar(255)') .addColumn('createdAt', sql`timestamp with time zone`, (cb) => cb.defaultTo(sql`current_timestamp`) ) .execute() }
Breeze through migrations and upgrades
Your needs and dependencies change constantly. It's easy to fall behind and can even bring your app to a sudden hault. ZappJS enables you to effortlessly adapt your existing codebase to new standards and upgrades, minimizing manual effort and reducing the scope for errors.
Migrating from Mongoose to Prisma
models: user: attributes: name: type: string location: type: string age: type: number
const mongoose = require('mongoose'); const User = mongoose.model( 'User', { name: String, location: String, age: Number } );
model User { id Int @id @default(autoincrement()) name String location String age Int }
Upgrading from Class Components to Function Components
pages: home: render: - h1: Hello, world
import { Component } from "react"; class HomePage extends Component { render() { return <h1>Hello, world</h1>; } }
import { FC } from "react"; const HomePage: FC = () => <h1>Hello, world</h1>;
Use alongside your handwritten code
Effortlessly blend automated and manual code. Designed for synergy, ZappJS allows you to generate essential code structures automatically while providing the flexibility to write your custom code alongside.
Choose whether to generate your models, handlers, both, or neither
models: post: attributes: title: type: string content: type: string
package models import "time" type Post struct { ID int `json:"id"` Title string `json:"title"` Content string `json:"content"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` }
package handlers import ( "net/http" "time" "github.com/gin-gonic/gin" "gorm.io/gorm" "my-app/models" ) func CreatePost(db *gorm.DB) gin.HandlerFunc { return func(c *gin.Context) { var newPost models.Post if err := c.ShouldBindJSON(&newPost); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } // write some other code db.Create(&newPost) c.JSON(http.StatusCreated, newPost) } }
Spec how you want
The power to define your specifications lies in your hands. Embrace the freedom to use industry-standard specifications for familiarity and best practices, or blaze your own trail with custom specifications tailored to your unique requirements.
Use a standard like Swagger or roll with your own.
paths: /pet: post: operationId: addPet requestBody: description: Create a new pet in the store content: application/json: schema: $ref: '#/components/schemas/Pet' required: true responses: '200': description: Successful operation content: application/json: schema: $ref: '#/components/schemas/Pet' '405': description: Invalid input
calls: addPet: description: Create a new pet in the store request: $ref: '#/models/pet' response: $ref: '#/models/pet'
Generate code in any language
ZappJS breaks down the barriers of language-specific limitations, offering you the freedom to generate code in the language of your choice.
Build anything
Apps, websites, APIs, desktop applications, CLI tools, games. Anything you can code manually, you can use ZappJS to generate all or part of your codebase.
Generate models for an API
models: user: attributes: name: type: string location: type: string age: type: number
const mongoose = require('mongoose'); const User = mongoose.model( 'User', { name: String, location: String, age: Number } );
Generate pages for a website
props: name: default: world type: string render: - h1: class: - text-bold - text-2xl - text-white text: Hello, {name}
import { FC } from "react"; interface Props { name?: string; } const Greeting: FC<Props> = ({ name = 'world' }) => { return ( <h1 className="text-bold text-2xl text-white"> Hello, {name} </h1> ); }
Generate a CLI program
name: string-util description: CLI to some JavaScript string utilities version: 0.8.0 commands: split: description: Split a string into substrings and display as an array arguments: - description: string to split type: string options: - flag: --first description: display just the first substring - flag: -s, --separator <char> description: separator character default: ,
const { Command } = require('commander'); const splitAction = require('./actions/split'); const program = new Command(); program .name('string-util') .description('CLI to some JavaScript string utilities') .version('0.8.0'); program.command('split') .description('Split a string into substrings and display as an array') .argument('<string>', 'string to split') .option('--first', 'display just the first substring') .option('-s, --separator <char>', 'separator character', ',') .action(splitAction); program.parse();
Leave anytime
If you ever want to stop using ZappJS, just remove the `.zapp` directory and keep shipping. We will miss you and are honored to be a part of your journey.
models: post: attributes: title: type: string content: type: string
package models import "time" type Post struct { ID int `json:"id"` Title string `json:"title"` Content string `json:"content"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` }
$ rm -rf .zapp
Want to learn more?
Check out the source code and follow us on X!