Step 1: Project Setup#
** Quick Tip: Each step has two parts. Part 1 shows you what to build. Part 2** explains why it works. Want to just build? Skip all Part 2 sections!
In this first step, you'll create your Jac project and understand the basic file structure.
Part 1: Building the App#
Step 1.1: Create Your Project#
Open your terminal and run:
This creates a new directory called todo-app with everything you need.
Step 1.2: Navigate to Your Project#
Step 1.3: Understand the Structure#
Your project now has these files:
todo-app/
├── app.jac # Your main application file (we'll work here!)
├── package.json # Node.js dependencies (auto-managed)
├── vite.config.js # Build configuration (you can ignore this)
└── README.md # Basic instructions
Important: We'll write ALL our code in app.jac - that's it!
Step 1.4: Create Your First App#
Open app.jac in your code editor and replace everything with this:
cl {
def app() -> any {
return <div>
<h1>Hello, Jac!</h1>
<p>My first full-stack app</p>
</div>;
}
}
Step 1.5: Run Your App#
In your terminal, run:
You'll see output like:
INFO: Started server process [12345]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8000
Step 1.6: View in Browser#
Open your browser and go to:
You should see "Hello, Jac!" and "My first full-stack app"
⏭ Want to skip the theory? Jump to Step 2: First Component
Part 2: Understanding the Concepts#
What is cl { ... }?#
cl stands for "client" - it means this code runs in the browser (frontend).
Think of it like this:
- Code inside
cl { }→ Runs in the browser (frontend) - Code outside
cl { }→ Runs on the server (backend)
What is def app() -> any?#
This is your main entry point - the function that Jac calls first.
Requirements:
- Must be named
app(by convention) - Must return JSX (HTML-like syntax)
- Located inside
cl { }block
Python analogy:
What is JSX?#
JSX lets you write HTML directly in your Jac code:
Key rules:
- Must have one root element
# Correct
return <div><h1>Title</h1><p>Text</p></div>;
# Wrong (two root elements)
return <h1>Title</h1><p>Text</p>;
- Self-closing tags need
/
- Use
{}to insert Jac code
How jac serve Works#
When you run jac serve app.jac:
- Jac compiler reads your
.jacfile - Frontend code (inside
cl) → Compiled to JavaScript - Backend code (outside
cl) → Stays as Python-like backend code - Single server serves both on port 8000
- Auto-reload watches for file changes (coming soon...)
It's like running a Flask/FastAPI server, but it ALSO compiles and serves your React frontend - all in one command!
File Organization#
For now, everything goes in app.jac. As your app grows, you can split into multiple files:
todo-app/
├── app.jac # Main app
├── components.jac # Reusable components
└── walkers.jac # Backend logic
But for this tutorial, we'll keep everything in one file for simplicity.
What You've Learned#
- How to create a Jac project
- Project structure basics
- What
cl { }means (client-side code) - The
def app()entry point - JSX basics (HTML in code)
- Running your app with
jac serve
Common Issues#
Issue: jac: command not found#
Solution: Install jac-client:
Issue: Port 8000 already in use#
Solution: Use a different port:
Then visit http://localhost:8080/page/app
Issue: Blank page in browser#
Check:
- Did you visit
/page/app(not just/)? - Check terminal for errors
- Make sure
app()has areturnstatement
Issue: Changes not showing#
Solution:
- Stop the server (Ctrl+C)
- Restart:
jac serve app.jac - Refresh browser
Quick Exercise#
Before moving on, try changing the text:
Save, refresh your browser, and see the changes!
Next Step#
Great! You have a running Jac app. Now let's learn about components - the building blocks of any UI.