Build Your First Construct
Let's build a simple todo list to learn the Construct patterns. This will take about 5 minutes.
1. Create Your File
Create a new file called App.tsx. This is the only file you need.
2. Generate with AI
Open Claude Code or OpenCode and ask it to build your Construct:
Try this prompt:
The AI will generate a complete Construct following all our standards because it has the @useworkapp/construct-skill installed.
3. Understand the Pattern
Here's what a complete Construct looks like. Let's break it down:
Imports
"use client";
import { useState, useEffect } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Checkbox } from "@/components/ui/checkbox";
import { Label } from "@/components/ui/label";
import { Plus, Trash2 } from "lucide-react";Always use "use client" at the top. Import only from shadcn/ui and lucide-react.
Types and Storage Key
interface Todo {
id: string;
text: string;
completed: boolean;
}
const STORAGE_KEY = "work-construct-todo-list";Always prefix your storage key with work-construct-to avoid conflicts.
State with localStorage
export default function App() {
const [todos, setTodos] = useState<Todo[]>(() => {
if (typeof window === "undefined") return [];
const saved = localStorage.getItem(STORAGE_KEY);
return saved ? JSON.parse(saved) : [];
});
useEffect(() => {
localStorage.setItem(STORAGE_KEY, JSON.stringify(todos));
}, [todos]);Initialize state from localStorage and save on every change. Check for window to handle SSR.
JSX Structure
return (
<div className="min-h-screen bg-background p-4 sm:p-6">
<Card className="mx-auto max-w-md">
<CardHeader>
<CardTitle>Todo List</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
{/* Form and list here */}
</CardContent>
</Card>
</div>
);Use Tailwind classes for styling. Always include responsive padding (p-4 sm:p-6).
Accessibility
<Button onClick={addTodo} aria-label="Add task">
<Plus className="h-4 w-4" />
</Button>
<Checkbox
id={todo.id}
checked={todo.completed}
onCheckedChange={() => toggleTodo(todo.id)}
/>
<Label htmlFor={todo.id}>{todo.text}</Label>Add aria-label to icon buttons. Connect labels to inputs with matching id/htmlFor.
4. Validate Your Code
Run the validator to check your Construct:
╔══════════════════════════════════════════════════════════════╗
║ WORK CONSTRUCT VALIDATOR ║
╚══════════════════════════════════════════════════════════════╝
✓ Construct passes all validations!
Common Mistakes to Avoid
Don't use fetch or axios
Constructs run in a sandbox without network access. Use localStorage only.
Don't use inline styles
Use Tailwind classes instead of style={{}}.
Don't forget the storage key prefix
Always use work-construct-your-name as your localStorage key.
Don't skip accessibility
Icon buttons need aria-label. Inputs need associated labels.