• Blog
  • Docs
  • Pricing
  • We’re hiring!
Log inSign up
stevekrouse

stevekrouse

beyond-text

Public
Starter template with client-side React & Hono server
Remix of templates/reactHonoStarter
Like
beyond-text
Home
Code
3
frontend
4
README.md
H
index.ts
Connections
Environment variables
Branches
2
Pull requests
Remixes
History
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
README.md
Code
/
README.md
Search
…
Viewing readonly version of main branch: v11
View latest version
README.md

Beyond Text — Chat

A minimal realtime chat app built on Val Town. Messages are stored in Val Town SQLite and streamed to every client over Server-Sent Events. A QR code of the app's own URL is shown in the sidebar so people can scan to join.

Features

  • 💬 Realtime chat via Server-Sent Events (no WebSockets needed)
  • 🗄️ Messages stored in Val Town SQLite
  • 📱 QR code of the site URL for easy joining
  • 👤 Username saved to localStorage (prompted on first visit)
  • 🧘 No auto-scroll, no auto-focus on the input

Architecture

Rendering mermaid diagram...

File structure

index.ts                        ← Hono backend: static + /api routes + SSE stream
frontend/
  index.html                    ← HTML shell (loads Twind + React)
  index.tsx                     ← React entrypoint (mounts <App />)
  favicon.svg                   ← App icon
  components/
    App.tsx                     ← Username gating (localStorage)
    UsernamePrompt.tsx          ← First-visit username form
    Chat.tsx                    ← Messages list, input, sidebar
    QRCode.tsx                  ← Renders a QR of the site URL

API

  • GET / — serves the React app
  • POST /api/messages — { username, text } → stores a message in SQLite
  • GET /api/messages?sinceId=N — fetch messages newer than N
  • GET /api/stream?sinceId=N — SSE stream of new messages (polls SQLite every 1.5s; emits hello, message, and ping events)

Notes on design choices

  • SSE instead of WebSockets: Val Town doesn't accept incoming WebSocket connections, so the server polls SQLite on a 1.5s loop and pushes new rows to each subscribed client as SSE events.
  • No auto-scroll / auto-focus: The messages pane scrolls only when the user scrolls, and the input is never programmatically focused.
  • Username in localStorage: A first-visit prompt stores the chosen name under the key beyond-text:username. A "change" button in the header clears it.
FeaturesVersion controlCode intelligenceCLIMCP
Use cases
TeamsAI agentsSlackGTM
DocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
AboutAlternativesPricingBlogNewsletterCareers
We’re hiring!
Brandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Open Source Pledge
Terms of usePrivacy policyAbuse contact
© 2026 Val Town, Inc.