Search
![scothis avatar](https://images.clerk.dev/oauth_github/img_2TV49Ptzlw3gHeusDYlPd8DutLU.jpeg)
myApi
@scothis
An interactive, runnable TypeScript val by scothis
Script
export function myApi(name) {
return "hi " + name;
val_7APnHlLC0n
@dhvanil
An interactive, runnable TypeScript val by dhvanil
HTTP
export default async function handler(req) {
try {
const result = await (async () => {
function fibonacci() {
let a = 0, b = 1;
while (b < 1000) {
web_ZOT5N4yReQ
@dhvanil
An interactive, runnable TypeScript val by dhvanil
HTTP
export async function web_ZOT5N4yReQ(req) {
return new Response(`<!DOCTYPE html>
// Create floating stars
function createStars() {
const stars = document.getElementById('stars');
// Terminal effect
async function terminalBoot() {
const terminal = document.getElementById('terminal');
![pomdtr avatar](https://images.clerk.dev/oauth_github/img_2RCoAITJZH1QencEgtVjh4Qirj4.jpeg)
password_auth
@pomdtr
Password Auth Middleware Protect your vals behind a password. Use session cookies to persist authentication. Usage import { passwordAuth } from "https://esm.town/v/pomdtr/password_auth?v=84";
export default passwordAuth(() => {
return new Response("OK");
}, { verifyPassword: (password) => password == Deno.env.get("VAL_PASSWORD") }); If you want to use an api token to authenticate: import { passwordAuth } from "https://esm.town/v/pomdtr/password_auth?v=84";
import { verifyToken } from "https://esm.town/v/pomdtr/verifyToken";
export default passwordAuth(() => {
return new Response("OK");
}, { verifyPassword: verifyToken }); TODO [x] allow to authenticate using a val town token [ ] add a way to send an email to ask a password from the val owner [ ] automatically extend the session [ ] automatically remove expired sessions FAQ How to sign out ? Navigate to <your-site>/signout .
Script
expiresAt: number;
async function createSessionTable(tableName: string) {
await sqlite.execute(`CREATE TABLE ${tableName} (
val_slug STRING NOT NULL
async function createSession(tableName: string, valSlug: string): Promise<Session> {
try {
throw e;
async function getSession(tableName: string, sessionID: string, valSlug: string): Promise<Session> {
try {
</html>`;
export function redirect(location: string): Response {
return new Response(null, {
const cookieName = "auth_session";
export function passwordAuth(next, options?: PasswordAuthOptions) {
const sessionTable = options?.sessionTable || "password_auth_session";
![stevekrouse avatar](https://images.clerk.dev/uploaded/img_2PqHa2Gsy93xQrjh2w78Xu0cChW.jpeg)
reloadOnSave
@stevekrouse
Live reload in new tabs When you're working on an HTML HTTP val in a new tab, it's annoying to have to manually reload the tab on every save. In the Val Town editor, you can hit cmd+enter, but there's nothing like that for a val in a new tab because Val Town doesn't control that new tab (like we control the iframe in the browser preview). However, you control that HTML via the fetch handler you're writing, so you can add a script that polls the Val Town API for the current version number of your val, and reload itself if it detects a new version. This val has a collection of helpers to help you do just that. Usage import { html } from "https://esm.town/v/stevekrouse/html";
import { reloadOnSaveFetchMiddleware } from "https://esm.town/v/stevekrouse/reloadOnSave";
export default reloadOnSaveFetchMiddleware(async function(req: Request): Promise<Response> {
return html(`<h1>Hello!!</h1>`);
})
Script
import { reloadOnSaveFetchMiddleware } from "https://esm.town/v/stevekrouse/reloadOnSave";
export default reloadOnSaveFetchMiddleware(async function(req: Request): Promise<Response> {
return html(`<h1>Hello!!</h1>`);
// this script runs client-side
export const reloadOnVals = async function(vals: ValRef[]) {
const valVersions = await Promise.all(vals.map(getCurrentValVersionNumber));
// experimental - don't use this
export function reloadOnSaveHonoMiddleware(vals: ValRef[] = [rootValRef()]): MiddlewareHandler {
return async function(c, next) {
await next();
* @param vals to watch
export function reloadOnSaveFetchMiddleware(
handler: (req: Request) => Response | Promise<Response>,
extremePlumCaribou
@ejfox
@jsxImportSource https://esm.sh/react
HTTP
import { marked } from "https://esm.sh/marked";
function App() {
const [vals, setVals] = useState([]);
</div>
async function fetchEmojiForName(name) {
try {
return '❓'; // Placeholder
function client() {
createRoot(document.getElementById("root")).render(<App />);
if (typeof document !== "undefined") { client(); }
async function server(request: Request): Promise<Response> {
const url = new URL(request.url);
headers: { 'Content-Type': 'application/json' }
// Generate new emoji using OpenAI
const { OpenAI } = await import("https://esm.town/v/std/openai");
const openai = new OpenAI();
const completion = await openai.chat.completions.create({
messages: [{ role: "user", content: `Generate a single emoji that best represents "${name}". Respond with only the emoji, nothing else.` }],
![com avatar](https://images.clerk.dev/oauth_github/img_2RWnSnTeKW3lDMDe6flk8enrKGM.png)
myApi
@com
An interactive, runnable TypeScript val by com
Script
export function myApi(name) {
return "hi " + name;
![benmanns avatar](https://images.clerk.dev/oauth_github/img_2Qvd3TUKQK9Y6iIaPB5lKwMlqq2.jpeg)
myApi
@benmanns
An interactive, runnable TypeScript val by benmanns
Script
export function myApi(name) {
return "hi " + name;
![vawogbemi avatar](https://images.clerk.dev/oauth_github/img_2TXrDk0iTsMgo2T7z93Wn4eqcgK.jpeg)
instantCursorsDemo
@vawogbemi
@jsxImportSource https://esm.sh/react
HTTP
import { createRoot } from "https://esm.sh/react-dom/client";
function InstantCursors() {
const db = init<
</Cursors>
function App() {
return (
</div>
function client() {
createRoot(document.getElementById("root")).render(<App />);
if (typeof document !== "undefined") { client(); }
export default async function server(request: Request): Promise<Response> {
return new Response(
async_handler
@dinavinter
An interactive, runnable TypeScript val by dinavinter
Script
import { yArrayIterator } from "https://esm.sh/@cxai/stream";
import * as Y from "https://esm.sh/yjs";
export function asyncHandler(id: string, actor: string) {
const doc = new Y.Doc({ guid: `@async.${id}`, meta: { collection: "async-handler" } });
const handled = doc.getMap(`@handler.${actor}`);
const queue = doc.getArray("@queue");
async function listen(handler: (event: any) => PromiseLike<void | any>) {
for await (const event of yArrayIterator(queue)) {
const eventMap = doc.getMap(`@handler.${actor}.${event.id}`);
honoGameTest
@andreterron
An interactive, runnable TypeScript val by andreterron
Script
import { honoHead } from "https://esm.town/v/andreterron/honoHead";
export async function honoGameTest(req: Request) {
const { Hono } = await import("npm:hono");
const { html } = await import("npm:hono/html");
![ryki avatar](https://images.clerk.dev/oauth_github/img_2RYnhWG6RMuPDA8XHghlIEY7CtK.jpeg)
myApi
@ryki
An interactive, runnable TypeScript val by ryki
Script
export function myApi(name) {
return "hi " + name;
![gregplumbly avatar](https://images.clerk.dev/oauth_github/img_2Skyb2dc462BaG4YVt7r1err47r.jpeg)
myApi
@gregplumbly
An interactive, runnable TypeScript val by gregplumbly
Script
export function myApi(name) {
return "hi " + name;
pingMe
@prepor
An interactive, runnable TypeScript val by prepor
Script
let { incrementer } = await import("https://esm.town/v/prepor/incrementer");
export function pingMe() {
incrementer += 1;
console.email(`How are you? ${incrementer}`);
![stevekrouse avatar](https://images.clerk.dev/uploaded/img_2PqHa2Gsy93xQrjh2w78Xu0cChW.jpeg)
geocode
@stevekrouse
* This code creates a geocoder widget similar to the Google Maps API search widget.
* It uses React for the frontend, the Cerebras API for LLM-based geocoding,
* and Leaflet for displaying the map.
HTTP
import debounce from "https://esm.sh/lodash.debounce";
function App() {
const [query, setQuery] = useState("");
</div>
function client() {
createRoot(document.getElementById("root")).render(<App />);
client();
async function server(request: Request): Promise<Response> {
if (request.method === "POST" && new URL(request.url).pathname === "/geocode") {
} catch (error) {
console.error("Error calling Cerebras API:", error);
return new Response(JSON.stringify({ error: "Failed to fetch suggestions" }), {