SpecUI breaks down the barriers of language-specific limitations, offering you the freedom to generate code in the language of your choice. Use or create generators for your favorite frameworks.
Your needs and dependencies change constantly. It's easy to fall behind and can even bring your app to a sudden hault. SpecUI enables you to effortlessly adapt your existing codebase to new standards and upgrades, minimizing manual effort and reducing the scope for errors.
pages:
index:
elements:
- tag: h1
text: 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>;
models:
task:
attributes:
id:
key: primary
type: number
description:
required: true
type: string
isCompleted:
default: false
type: boolean
pages:
index:
elements:
- tag: ul
elements:
model: tasks
name: task
key: $task.id
tag: li
class: flex justify-between min-w-96
elements:
- tag: label
text: $task.description
for: isCompleted
- tag: component
component: checkbox
defaultChecked: $task.isCompleted
name: isCompleted
import type { InferGetStaticPropsType, GetStaticProps } from 'next'
import { type Task, db } from '@/lib/db';
export default function Home({
tasks,
}: InferGetStaticPropsType<typeof getStaticProps>) {
return (
<ul className="flex flex-col gap-2">
{tasks.map((task) => (
<li key={task.id}>
<label htmlFor="isCompleted">{task.description}</label>
<Checkbox defaultChecked={task.isCompleted} name="isCompleted" />
</li>
))}
</ul>
);
}
export const getStaticProps = (async (context) => {
const tasks = await db
.selectFrom('tasks')
.selectAll()
.execute();
return { props: { tasks } };
}) satisfies GetStaticProps<{
tasks: Task[]
}>
import type { InferGetStaticPropsType, GetStaticProps } from 'next'
import { type Task, db } from '@/lib/db';
export default async function Home() {
const tasks = await db
.selectFrom('tasks')
.selectAll()
.execute();
return (
<ul className="flex flex-col gap-2">
{tasks.map((task) => (
<li key={task.id}>
<label htmlFor="isCompleted">{task.description}</label>
<Checkbox defaultChecked={task.isCompleted} name="isCompleted" />
</li>
))}
</ul>
);
}
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. SpecUI 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()
}
Many code generators enable to produce your code once.
models:
user:
attributes:
name:
type: string
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
models:
user:
attributes:
name:
type: string
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
models:
user:
attributes:
name:
type: string
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
models:
user:
attributes:
name:
type: string
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
Effortlessly blend automated and manual code. Designed for synergy, SpecUI allows you to generate essential code structures automatically while providing the flexibility to write your custom code alongside.
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)
}
}
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.
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'
If you ever want to stop using SpecUI, just remove the `.specui` 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 .specui