MusicBox - Val.town React Project

This is a React project built for val.town, a platform for building and deploying serverless functions.

Project Structure

  • main.tsx - Main React component with server-side rendering
  • deno.json - Deno configuration with TypeScript and val.town types
  • .vt/ - Val.town CLI configuration and state
  • .vtignore - Files to ignore when deploying to val.town

Technology Stack

  • Runtime: Deno
  • Framework: React with server-side rendering
  • JSX: Uses https://esm.sh/react as JSX import source
  • Server Rendering: react-dom/server for renderToString
  • Platform: Val.town serverless functions
  • Database: SQLite (built-in) and PostgreSQL (via Neon integration)

Development Commands

Val.town CLI Commands

# Deploy to val.town vt deploy # Run locally vt dev # Check val status vt status # Pull latest from val.town vt pull # Push changes to val.town vt push

Linting and Type Checking

# Lint with Deno deno lint # Type check with Deno deno check main.tsx # Format code deno fmt

Project Configuration

Deno Configuration

  • TypeScript strict mode disabled for flexibility
  • Dom and Deno types included
  • Val.town types automatically imported
  • Experimental features enabled for Node.js compatibility

Val.town Integration

  • Val ID: 364f6226-8700-11f0-9096-0224a6c84d84
  • Branch ID: 364fb17c-8700-11f0-9096-0224a6c84d84
  • Current version: 5

Development Guidelines

  1. JSX Import: Always use /** @jsxImportSource https://esm.sh/react */ at the top of React files
  2. Server-side Rendering: Use renderToString for HTML responses
  3. Request Handling: Export functions that take Request and return Response
  4. Dependencies: Use npm: prefix for npm packages or ESM URLs
  5. Types: Val.town types are automatically available

Example HTTP Handler

/** @jsxImportSource https://esm.sh/react */ import { renderToString } from "npm:react-dom/server"; export const myHandler = (request: Request) => new Response(renderToString(<div>Hello World</div>), { headers: { "Content-Type": "text/html", }, });

Database Integration

SQLite (Built-in)

Val.town provides SQLite database access with every account:

import { sqlite } from "https://esm.sh/@valtown/sdk"; // Example SQLite usage const db = sqlite("mydb"); await db.execute( "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)", ); await db.execute("INSERT INTO users (name) VALUES (?)", ["John"]); const users = await db.execute("SELECT * FROM users");

SQLite Limits:

  • Free: 10MB storage
  • Paid: Up to 1GB storage
  • Powered by Turso

PostgreSQL (via Neon)

For more advanced database needs, integrate with Neon PostgreSQL:

  1. Setup:

    • Create Neon project at neon.tech
    • Copy PostgreSQL connection URL
    • Add as environment variable in Val.town
  2. Usage:

import { Client } from "https://deno.land/x/postgres/mod.ts"; const client = new Client(Deno.env.get("DATABASE_URL")); await client.connect(); // Example query const result = await client .queryObject`SELECT * FROM users WHERE id = ${userId}`; await client.end();

PostgreSQL Best Practices:

  • Use PostgreSQL v14 for better compatibility
  • Always use prepared statements
  • Choose US region for lower latency
  • Store connection URL as environment variable

Other Database Options

  • Neon Postgres - Serverless PostgreSQL with branching
  • PlanetScale - Serverless MySQL platform
  • Supabase - PostgreSQL with real-time features
  • Upstash - Redis and Kafka for serverless

Useful Resources

Notes

  • Lock file is disabled ("lock": false) for flexibility
  • Node modules directory is disabled ("node_modules_dir": false)
  • Unstable Deno features are enabled for compatibility
  • Project uses Git for version control alongside val.town versioning
  • use conventionl commits for commit messages. Commit early and often - in sensible increments.