You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
> **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.
7
9
@@ -10,7 +12,7 @@
10
12
Inspired by [Phoenix LiveView](https://hexdocs.pm/phoenix_live_view/) | [Datastar](https://data-star.dev/) | [HTMX](https://htmx.org/)
11
13
12
14
> [!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.
14
16
15
17
## Quick Start
16
18
@@ -21,7 +23,7 @@ bun install
21
23
bun run dev
22
24
```
23
25
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.
25
27
26
28
Now edit `app.tsx`:
27
29
@@ -63,29 +65,13 @@ Your app is live. No Docker, no config, no CI/CD setup.
63
65
64
66
## Why Hyperstar?
65
67
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.
**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.
80
71
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.
82
73
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.
89
75
90
76
---
91
77
@@ -127,6 +113,7 @@ Hyperstar has three types of state, each serving a different purpose:
127
113
│ SIGNALS (Client State) │
128
114
│ • Lives in browser memory only │
129
115
│ • Instant updates, no server roundtrip │
116
+
│ • Server can update via ctx.patchSignals() │
130
117
│ • Use for: form inputs, UI tabs, modals, hover state │
> **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
+
278
268
### Other Platforms
279
269
280
270
Since Hyperstar apps are standard Bun servers, deploy anywhere:
@@ -369,11 +359,18 @@ app.cron("sessionSync", {
369
359
app.app({
370
360
store: { online: 0 },
371
361
362
+
onStart: (ctx) => {
363
+
// Called once when server starts
364
+
console.log("Server started")
365
+
},
366
+
372
367
onConnect: (ctx) => {
368
+
// Called when a client connects
373
369
ctx.update((s) => ({ ...s, online: s.online+1 }))
374
370
},
375
371
376
372
onDisconnect: (ctx) => {
373
+
// Called when a client disconnects
377
374
ctx.update((s) => ({ ...s, online: s.online-1 }))
378
375
},
379
376
@@ -432,7 +429,6 @@ app.app({
432
429
No ORM, no connection pooling, no Redis - just `bun:sqlite`. This works because:
433
430
- Hyperstar apps run on a single server instance
434
431
- Bun's SQLite is synchronous and fast
435
-
- The VM (like Sprites) hibernates when idle, preserving your data
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