Skip to content

Commit f1fdb67

Browse files
committed
fix: load client bundle
1 parent cf5ee54 commit f1fdb67

17 files changed

Lines changed: 1678 additions & 47 deletions

File tree

.changeset/orange-crabs-add.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"hyperstar": minor
3+
"hyperstar-cli": minor
4+
---
5+
6+
fixes

README.md

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
# Hyperstar
44

5+
[![Discord](https://img.shields.io/badge/Discord-Join%20Us-5865F2?logo=discord&logoColor=white)](https://discord.gg/QsKYQhdqNu)
6+
57
> [!CAUTION]
68
> **Very Beta** - This is experimental software. The API changes frequently and will break your code. Don't use this for anything production-critical. Great for prototypes, internal tools, and fun real-time multiplayer apps.
79
@@ -10,7 +12,7 @@
1012
Inspired by [Phoenix LiveView](https://hexdocs.pm/phoenix_live_view/) | [Datastar](https://data-star.dev/) | [HTMX](https://htmx.org/)
1113

1214
> [!TIP]
13-
> **Built for Vibe Coding** - JSX that feels like React, but there's no client bundle, no hydration, no state sync bugs. The server owns everything. Live, realtime UI, directly from the server.
15+
> **Built for Vibe Coding** - JSX that feels like React, but there's no client bundle, no hydration, no state sync bugs. The server owns everything. Live, realtime UI, directly from the server. When you use `bunx hyperstar-cli create`, your project includes a Claude Code skill that teaches Claude how to build Hyperstar apps. If you're not using the CLI, you can copy the skill from [`packages/cli/skill/SKILL.md`](https://github.com/longtailLABS/hyperstar/blob/master/packages/cli/skill/SKILL.md) into your project's `.claude/skills/` directory.
1416
1517
## Quick Start
1618

@@ -21,7 +23,7 @@ bun install
2123
bun run dev
2224
```
2325

24-
Open http://localhost:3000 - you have a working app. Edit `app.tsx` and save - the browser updates instantly.
26+
Open http://localhost:3000 - you have a working app.
2527

2628
Now edit `app.tsx`:
2729

@@ -63,29 +65,13 @@ Your app is live. No Docker, no config, no CI/CD setup.
6365

6466
## Why Hyperstar?
6567

66-
### The Old Way (Pain)
68+
**Zero client code.** Your entire app lives on the server. No React components, no client-side state management, no API routes to wire up. Just TypeScript functions that update state and JSX that renders it.
6769

68-
```
69-
React + Next.js + TanStack Query + WebSockets + Redis + ...
70-
71-
1. Write React components
72-
2. Set up API routes
73-
3. Add TanStack Query for data fetching
74-
4. Add WebSocket server for real-time
75-
5. Sync client state with server state
76-
6. Handle loading states everywhere
77-
7. Deal with cache invalidation
78-
8. Cry yourself to sleep
79-
```
70+
**Real-time by default.** Every state change automatically syncs to all connected clients. User A clicks a button, User B sees it instantly. No WebSocket setup, no pub/sub configuration, no cache invalidation.
8071

81-
### The Hyperstar Way (Joy)
72+
**One mental model.** Server state is the source of truth. No wondering if the client is out of sync, no optimistic updates gone wrong, no race conditions between tabs.
8273

83-
```
84-
Hyperstar
85-
86-
1. Write a view function and actions to update state
87-
2. Done. It's real-time. It syncs. It works.
88-
```
74+
**Ship faster.** Internal tools, prototypes, multiplayer games, live dashboards - build them in seconds instead of hours. When the server owns everything, there's just less to think about.
8975

9076
---
9177

@@ -127,6 +113,7 @@ Hyperstar has three types of state, each serving a different purpose:
127113
│ SIGNALS (Client State) │
128114
│ • Lives in browser memory only │
129115
│ • Instant updates, no server roundtrip │
116+
│ • Server can update via ctx.patchSignals() │
130117
│ • Use for: form inputs, UI tabs, modals, hover state │
131118
└─────────────────────────────────────────────────────────────────┘
132119
```
@@ -145,7 +132,7 @@ const setTheme = app.action("setTheme", { theme: Schema.String }, (ctx, { theme
145132
ctx.updateUserStore((u) => ({ ...u, theme }))
146133
})
147134

148-
// Client-side: instant UI state
135+
// Client-side: instant UI state (server can also update via ctx.patchSignals)
149136
const { tab } = app.signals
150137
<button hs-on:click="$tab.value = 'settings'">Settings</button>
151138
```
@@ -275,6 +262,9 @@ export SPRITE_TOKEN=your_token
275262
bunx hyperstar-cli deploy
276263
```
277264

265+
> [!NOTE]
266+
> **Sprites and Background Tasks** - Sprites hibernate when idle to save costs. When a sprite sleeps, `app.repeat()` and `app.cron()` timers pause. They resume when a user reconnects. For apps that need always-on timers (like polling external APIs), deploy to a traditional always-on server instead.
267+
278268
### Other Platforms
279269

280270
Since Hyperstar apps are standard Bun servers, deploy anywhere:
@@ -369,11 +359,18 @@ app.cron("sessionSync", {
369359
app.app({
370360
store: { online: 0 },
371361

362+
onStart: (ctx) => {
363+
// Called once when server starts
364+
console.log("Server started")
365+
},
366+
372367
onConnect: (ctx) => {
368+
// Called when a client connects
373369
ctx.update((s) => ({ ...s, online: s.online + 1 }))
374370
},
375371

376372
onDisconnect: (ctx) => {
373+
// Called when a client disconnects
377374
ctx.update((s) => ({ ...s, online: s.online - 1 }))
378375
},
379376

@@ -432,7 +429,6 @@ app.app({
432429
No ORM, no connection pooling, no Redis - just `bun:sqlite`. This works because:
433430
- Hyperstar apps run on a single server instance
434431
- Bun's SQLite is synchronous and fast
435-
- The VM (like Sprites) hibernates when idle, preserving your data
436432

437433
### Dynamic Title and Favicon
438434

bun.lock

Lines changed: 18 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/hn-uncensored/README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# HN Uncensored
2+
3+
Monitor Hacker News for suspicious rank drops that might indicate flagging or moderation.
4+
5+
## How It Works
6+
7+
Stories on HN sometimes vanish from the front page without explanation. This app polls the top 90 stories every 5 minutes and uses **z-score anomaly detection** to flag unusual rank drops.
8+
9+
### Z-Score Detection
10+
11+
Instead of a simple threshold ("dropped 15+ positions"), we ask: *"Is this drop statistically unusual for this story?"*
12+
13+
Each story maintains a rolling window of rank changes. When a new drop occurs, we compute how many standard deviations it is from that story's normal behavior. A z-score > 3.0 means the drop is in the 99.7th percentile of unusualness.
14+
15+
Key parameters:
16+
- `lag: 24` - rolling window size (24 polls at 5‑min intervals)
17+
- `minDataPoints: 6` - warm‑up before alerts (≈30 minutes at 5‑min polls)
18+
- `threshold: 3.0` - 3 standard deviations = statistically significant
19+
- `influence: 0.2` - anomalies only contribute 20% to the filtered baseline (prevents corruption)
20+
- `minDrop: 5` - ignore tiny rank wiggles
21+
22+
### Severity Scoring
23+
24+
Alerts are scored based on:
25+
- **Z-score** - How anomalous the drop was (z * 15 points)
26+
- **Score rising** - +25 if upvotes are increasing (very suspicious)
27+
- **Off list** - +20 if story fell off top 90 entirely
28+
29+
## Running
30+
31+
```bash
32+
cd examples/hn-uncensored
33+
bun install
34+
bun dev
35+
```
36+
37+
Open http://localhost:3014
38+
39+
## Data
40+
41+
Persistence is saved to `./data/hn-uncensored.json` - this includes all tracked stories, history snapshots, detector state, and alerts.

0 commit comments

Comments
 (0)