DEV Community

Alex Spinov
Alex Spinov

Posted on

Val Town Has a Free API — Deploy Server Functions from Your Browser

Val Town lets you write and deploy small server-side functions directly in your browser. Cron jobs, HTTP endpoints, email handlers — all as tiny scripts called 'vals'.

Why Val Town?

  • Instant deploy — write code in browser, it's live immediately
  • HTTP endpoints — each val gets a public URL
  • Cron jobs — scheduled execution built-in
  • Email handlers — receive and process emails
  • Free tier — generous for small projects

HTTP Endpoint

// Creates: https://username-hello.web.val.run
export default function(req: Request): Response {
  const url = new URL(req.url);
  const name = url.searchParams.get('name') || 'World';
  return Response.json({ message: `Hello, ${name}!` });
}
Enter fullscreen mode Exit fullscreen mode

Cron Job

import { email } from 'https://esm.town/v/std/email';

// Runs every day at 9 AM
export default async function() {
  const response = await fetch('https://api.github.com/repos/denoland/deno/releases/latest');
  const release = await response.json();

  await email({
    subject: `Deno ${release.tag_name} released!`,
    text: release.body,
  });
}
Enter fullscreen mode Exit fullscreen mode

API Proxy

export default async function(req: Request): Response {
  const url = new URL(req.url);
  const query = url.searchParams.get('q');

  const response = await fetch(
    `https://api.github.com/search/repositories?q=${query}&sort=stars`,
    { headers: { 'User-Agent': 'val-town' } }
  );

  const data = await response.json();
  const repos = data.items.slice(0, 5).map(r => ({
    name: r.full_name,
    stars: r.stargazers_count,
    url: r.html_url,
  }));

  return Response.json(repos);
}
Enter fullscreen mode Exit fullscreen mode

SQLite Database

import { sqlite } from 'https://esm.town/v/std/sqlite';

// Create table
await sqlite.execute(`
  CREATE TABLE IF NOT EXISTS visits (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    path TEXT,
    timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
  )
`);

export default async function(req: Request): Response {
  const url = new URL(req.url);

  // Log visit
  await sqlite.execute('INSERT INTO visits (path) VALUES (?)', [url.pathname]);

  // Get stats
  const result = await sqlite.execute('SELECT COUNT(*) as count FROM visits');

  return Response.json({ totalVisits: result.rows[0][0] });
}
Enter fullscreen mode Exit fullscreen mode

Blob Storage

import { blob } from 'https://esm.town/v/std/blob';

// Store data
await blob.setJSON('config', { theme: 'dark', lang: 'en' });

// Read data
const config = await blob.getJSON('config');
Enter fullscreen mode Exit fullscreen mode

Need serverless data endpoints? Check out my Apify actors for web scraping APIs, or email spinov001@gmail.com for custom solutions.

Val Town, Cloudflare Workers, or Deno Deploy — which serverless platform do you use? Share below!

Top comments (0)