Quick Start
Get up and running with Peak.js in just a few minutes! This guide will walk you through creating your first reactive component.
Installation
Peak.js requires no build tools or complex setup. Simply include it in your HTML file:
Option 1: Load from a CDN
<!-- index.html -->
<!doctype html>
<head>
<title>My Peak.js App</title>
</head>
<body>
<x-app></x-app>
<script type="module">
import { component } from 'https://unpkg.com/@peak-js/core'
component('x-app', '/components/x-app.html')
</script>
</body>
Option 2: Install via Package Manager
# install via npm or yarn etc
npm install peak-js
// main.js
import { component } from 'peak-js/core'
component('x-app', '/components/x-app.html')
Your First Component
Let's create a simple counter component to demonstrate Peak.js basics.
1. Create the Component File
Create a file called components/x-counter.html
:
<!-- components/x-counter.html -->
<template>
<div class="counter">
<h2>Counter Example</h2>
<div class="count-display">
<span class="count" x-text="count"></span>
</div>
<div class="buttons">
<button @click="decrement" :disabled="count <= 0">-</button>
<button @click="increment">+</button>
</div>
<p class="status" x-text="statusMessage"></p>
<button @click="reset" x-show="count != 0">Reset</button>
</div>
</template>
<script>
export default class {
initialize() {
this.count = 0
}
get statusMessage() {
if (this.count === 0) return "Click + to start counting!"
if (this.count === 1) return "You've got one!"
if (this.count <= 10) return `Count is ${this.count}`
return "You're counting high!"
}
increment() {
this.count++
}
decrement() {
this.count--
}
reset() {
this.count = 0
}
}
</script>
<style>
.counter {
max-width: 300px;
margin: 0 auto;
padding: 20px;
border: 2px solid #e2e8f0;
border-radius: 8px;
text-align: center;
font-family: system-ui, sans-serif;
}
.count-display {
margin: 20px 0;
}
.count {
font-size: 3rem;
font-weight: bold;
color: #2563eb;
}
.buttons {
display: flex;
gap: 10px;
justify-content: center;
margin: 20px 0;
}
button {
padding: 10px 20px;
border: 1px solid #d1d5db;
border-radius: 6px;
cursor: pointer;
font-size: 1rem;
&:hover:not(:disabled) {
background: #f3f4f6;
}
&:disabled {
opacity: 0.5;
cursor: not-allowed;
}
}
.status {
color: #6b7280;
font-style: italic;
}
</style>
2. Create Your HTML Page
Create an index.html
file:
<!doctype html>
<head>
<title>My First Peak.js App</title>
<style>
body {
font-family: system-ui, sans-serif;
text-align: center;
}
</style>
</head>
<body>
<div class="container">
<h1>Welcome to Peak.js!</h1>
<x-counter></x-counter>
</div>
<script type="module">
import { component } from 'https://unpkg.com/@peak-js/core'
component('x-counter', './components/x-counter.html')
</script>
</body>
3. Serve Your App
Since we're using ES modules, you'll need to serve your files over HTTP (not file://
). You can use any static file server:
# static file server
python -m http.server 8000
Open your browser to http://localhost:8000
and you'll see your counter component in action!
What's Happening?
Let's break down what makes this work:
Component Registration
component('x-counter', './components/x-counter.html')
This registers a new custom element called <x-counter>
that loads its template from the specified file.
Reactive Data
initialize() {
this.count = 0 // This becomes reactive automatically
}
Any property you set on this
becomes reactive, meaning the UI updates automatically when the value changes.
Template Directives
x-text="count"
- Displays the value ofcount
@click="increment"
- Calls theincrement
method when clicked:disabled="count <= 0"
- Binds the disabled attribute to an expressionx-show="count > 0"
- Shows/hides the element based on condition
Computed Properties
get statusMessage() {
// This recalculates whenever 'count' changes
if (this.count === 0) return "Click + to start counting!"
// ...
}
Getter methods automatically become computed properties that update when their dependencies change.
Next Steps
Now that you have a basic component working, try these exercises:
Exercise 1: Add a Step Size
Modify the counter to allow custom step sizes:
initialize() {
this.count = 0
this.step = 1
}
increment() {
this.count += this.step
}
decrement() {
this.count -= this.step
}
Add an input to control the step size:
<input type="number" x-model="step" min="1" max="10">
Exercise 2: Create a Todo List
Create a new component components/x-todo-list.html
:
<template>
<div class="todo-list">
<h2>My Todo List</h2>
<form @submit.prevent="addTodo">
<input x-model="newTodo" placeholder="What needs to be done?" required>
<button type="submit">Add</button>
</form>
<ul x-show="todos.length > 0">
<li x-for="todo in todos" :key="todo.id">
<input type="checkbox" x-model="todo.completed">
<span :class="{ completed: todo.completed }" x-text="todo.text"></span>
<button @click="removeTodo(todo)">×</button>
</li>
</ul>
<p x-show="todos.length === 0">No todos yet! Add one above.</p>
</div>
</template>
<script>
export default class {
initialize() {
this.todos = []
this.newTodo = ""
}
addTodo() {
if (this.newTodo.trim()) {
this.todos.push({
id: Date.now(),
text: this.newTodo.trim(),
completed: false
})
this.newTodo = ""
}
}
removeTodo(todoToRemove) {
this.todos = this.todos.filter(todo => todo !== todoToRemove)
}
}
</script>
<style>
/* Add your todo list styles here */
</style>
Exercise 3: Component Communication
Create a parent component that manages multiple counters:
<!-- components/x-counter-manager.html -->
<template>
<div>
<h2>Counter Manager</h2>
<p>Total across all counters: <span x-text="totalCount"></span></p>
<div x-for="counter in counters" :key="counter.id">
<x-counter @count-changed="updateTotal"></x-counter>
</div>
<button @click="addCounter">Add Counter</button>
</div>
</template>
Common Patterns
As you build more components, here are some patterns you'll use frequently:
Form Handling
<form @submit.prevent="handleSubmit">
<input x-model="form.email" type="email" required>
<input x-model="form.password" type="password" required>
<button type="submit" :disabled="!isFormValid">Submit</button>
</form>
Loading States
<div x-show="loading">Loading...</div>
<div x-show="!loading">
<!-- Your content -->
</div>
Error Handling
<div x-show="error" class="error">
<p x-text="error"></p>
<button @click="clearError">Dismiss</button>
</div>
Resources
- Template Directives Guide - Learn all available directives
- Reactivity Guide - Understand how reactivity works
- Component Guide - Deep dive into component features
- Event Handling - Master event handling patterns
You're now ready to build amazing reactive applications with Peak.js! 🎉