Magic-link authentication for Val Town, powered by Better Auth. Click Remix and you have a working auth-protected app — no setup required.
It uses Val Town SQLite for the user/session database and Val Town Email to send the magic links. Sending magic links to anyone other than yourself requires Val Town Pro.
Rendering mermaid diagram...
index.ts ← Hono entrypoint; mounts Better Auth at /api/auth/*
backend/
auth.ts ← Better Auth instance (server)
schema.ts ← Creates the user/session/account/verification tables
frontend/
index.html ← HTML shell (loads Twind + React)
index.tsx ← React entrypoint (mounts <App />)
lib/
auth-client.ts ← Better Auth React client (useSession, signIn, signOut)
components/
App.tsx ← Root: shows <SignIn /> or <Dashboard /> based on session
SignIn.tsx ← Email form that calls signIn.magicLink
Dashboard.tsx ← Signed-in view with sign-out button
authClient.signIn.magicLink({ email }), which POSTs to
/api/auth/sign-in/magic-link.verification table, and
calls our sendMagicLink callback in backend/auth.ts. The callback uses
std/email to send the link./api/auth/magic-link/verify?token=….
Better Auth validates the token, creates a row in session, sets a secure
cookie, and redirects to /.useSession() re-fetches /api/auth/get-session, the user
object becomes available, and <App /> renders <Dashboard />.Better Auth has a rich plugin ecosystem. Common next steps:
emailAndPassword.enabled to true in
backend/auth.ts. No plugin needed.socialProviders to your auth
config and store the client IDs/secrets as env vars. See the
social providers docs.frontend/lib/auth-client.ts.After enabling new methods, you may need new database columns. See the
database concepts page — for
SQLite you'll add the columns directly to backend/schema.ts.
BETTER_AUTH_SECRET env var to a random string from
generate-random-signing-key.val.run.baseURL.allowedHosts in backend/auth.ts to the exact hosts you
serve from (e.g. ["myapp.com", "*.web.val.run"]).std/sqlite is already an
@libsql/client Client, so we hand it straight to LibsqlDialect. Zero
database setup.