Search

Results include substring matches and semantically similar vals. Learn more
applemetabank avatar
billGeneratorWebApp
@applemetabank
@jsxImportSource https://esm.sh/react@18.2.0
HTTP
/** @jsxImportSource https://esm.sh/react@18.2.0 */
import React, { useState, useEffect } from "https://esm.sh/react@18.2.0";
import { createRoot } from "https://esm.sh/react-dom@18.2.0/client";
function generatePDFServerSide(invoiceData, template) {
// Client Info
.text(`${invoiceData.clientInfo.name}`)
.text(`${invoiceData.clientInfo.address}`)
.text(`${invoiceData.clientInfo.email}`);
const [clientInfo, setClientInfo] = useState({
clientInfo,
shivdwipgo avatar
fileManagerApp
@shivdwipgo
@jsxImportSource https://esm.sh/react@18.2.0
Script
/** @jsxImportSource https://esm.sh/react@18.2.0 */
import React, { useState, useEffect } from "https://esm.sh/react@18.2.0";
import { createRoot } from "https://esm.sh/react-dom@18.2.0/client";
function FileManager() {
</div>
function client() {
// Add long press functionality
createRoot(document.getElementById("root")).render(<FileManager />);
if (typeof document !== "undefined") { client(); }
export default async function server(request: Request): Promise<Response> {
const url = new URL(request.url);
// Server-side file management endpoints (unchanged from previous implementation)
if (url.pathname === '/list-files') {
jxnblk avatar
resrv_example
@jxnblk
@jsxImportSource https://esm.sh/react
HTTP
/** @jsxImportSource https://esm.sh/react */
import resrv, { React } from "https://esm.town/v/jxnblk/resrv";
function App() {
const [count, setCount] = React.useState(0);
return (
<h1>Resrv</h1>
<p>React SSR with client-side hydration in Val Town</p>
<pre>{count}</pre>
stevekrouse avatar
yc_finder
@stevekrouse
YC Company Finder In an effort to get more companies using Val Town, I wanted to see which of our existing userbase was part of a YC company. I found this wonderful google sheet with all YC companies, and had Townie make me this interface to join it with an exported CSV of our users table. All the compute happens client-side, so it's safe for you to run on your customer lists too. If you want any changes, fork it & have Townie customize it for you. Feel free to send me a pull request or leave a comment :)
HTTP
join it with an exported CSV of our users table.
All the compute happens client-side, so it's safe for you to run on your customer lists too.
If you want any changes, fork it & have Townie customize it for you. Feel free to send me a pull request or leave a comment :
/** @jsxImportSource https://esm.sh/react */
import { csvParse } from "https://esm.sh/d3-dsv@3.0.1";
import React, { useEffect, useState } from "https://esm.sh/react";
import { createRoot } from "https://esm.sh/react-dom/client";
interface YCCompany {
<li>You get a detailed report of matches, enriched with YC company data</li>
<li>This is done entirely client-side. None of your data hits our servers or is stored</li>
</ol>
fetchYCCompanies();
const handleFileUpload = (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
reader.readAsText(file);
const handleSubmit = (event: React.FormEvent) => {
event.preventDefault();
</div>
function client() {
createRoot(document.getElementById("root")!).render(<App />);
if (typeof document !== "undefined") {
client();
export default async function server(request: Request): Promise<Response> {
trob avatar
multilingualchatroom
@trob
A simple chat room to share with friends of other languages, where each user can talk in their own language and see others' messages in their own language. Click and hold a translated message to see the original message. Open the app in a new window to start your own, unique chatroom that you can share with your friends via the room URL. TODO: BUG: fix the issue that keeps old usernames in the "[User] is typing" section after a user changes their name. BUG: Username edit backspaces is glitchy. UI: Update the title for each unique chatroom to make the difference clear. UI: mobile friendly. Feature: the ability for the message receiver to select a part of a translation that is confusing and the author will see that highlight of the confusing words and have the opportunity to reword the message or... Feature: bump a translation to a higher LLM for more accurate translation. Feature: use prior chat context for more accurate translations. Feature: Add video feed for non-verbals while chatting.
HTTP
/** @jsxImportSource https://esm.sh/react */
import { nanoid } from "https://esm.sh/nanoid";
import React, { useCallback, useEffect, useState } from "https://esm.sh/react";
import { createRoot } from "https://esm.sh/react-dom/client";
const languages = [
</div>
function Sidebar({ users, language, handleLanguageChange, roomUrl, copyToClipboard, copied, t }) {
return (
<div className="sidebar">
<UserList users={users} t={t} />
</div>
<Sidebar
users={users}
</div>
function client() {
createRoot(document.getElementById("root")).render(<App />);
if (typeof document !== "undefined") { client(); }
export default async function server(request: Request): Promise<Response> {
background-color: #e0e0e0;
.sidebar {
width: 250px;
szymonator avatar
surfboardDemoSchedule2
@szymonator
// WELCOME TO THE API DEMO
HTTP
// DO NOT EDIT THE BELOW
/** @jsxImportSource https://esm.sh/react */
import { useEffect, useState } from "https://esm.sh/react";
import { renderToString } from "npm:react-dom/server";
// BELOW ARE THE HOURLY RATES FOR AN ON CALL SHIFT, AND A REGULAR SHIFT. THE DEFAULT IS £24 AND £12.
// IF YOU DON'T WANT THIS DEFAULT, REMOVE THE TWO FORWARD SLASHES FROM THE TWO LINES OF CODE AND
// WRITE THE DATE IN THE FORMAT: "YYYY-MM-DD", INSIDE THE PROVIDED QUOTES. DO NOT CHANGE ANYTHING ELSE.
// PLEASE DO NOT SET THE START DATE TO BE LATER THAN THE END DATE, ALSO KEEP THE POSITIONING OF THE LINES THE SAME.
// if (typeof document !== "undefined") {
// const { hydrateRoot } = await import("https://esm.sh/react-dom/client");
// const scheduleData = await getSchedule();
const scheduleData = await getSchedule();
const { renderToReadableStream } = await import("https://esm.sh/react-dom/server");
const stream = await renderToReadableStream(<App data={scheduleData} />, { bootstrapModules: [import.meta.url] });
loading avatar
xp
@loading
WinSky BlueSky frontend that resembles an early 2000s forum
HTTP
/** @jsxImportSource https://esm.sh/react@18.3.1 */
import { AppBskyActorDefs, AppBskyFeedDefs, AtpAgent, RichText } from "https://esm.sh/@atproto/api@0.13.15";
import { createRoot } from "https://esm.sh/react-dom@18.3.1/client";
import React, { useCallback, useEffect, useState } from "https://esm.sh/react@18.3.1";
function App() {
<div className="max-w-4xl mx-auto p-4 flex">
{/* Start menu-like sidebar */}
<div className="w-48 mr-4">
</div>
function client() {
createRoot(document.getElementById("root")!).render(<App />);
if (typeof document !== "undefined") {
client();
const manifest = {
short_name: "WinSky",
description: "A Windows XP-styled BlueSky client",
start_url: "/",
<meta name="theme-color" content="#3A6EA5">
lPODUyxrbL4v/C8oOxSie7lTd+Z/Hlzp4Geq+vkZbQXDBME0s5q6wOqnINrdK0J0vmgNjw2SA8sTptSIdeIMAS+a6+c9+sYCRv8g18TeBNEoPzAK7oYCOdJP+zV+a
<script src="https://cdn.tailwindcss.com"></script>
stevekrouse avatar
gemini_coder
@stevekrouse
This is an AI code assistant powered by Cerebras , running llama3.3-70b. Inspired by Hassan's Llama Coder . Setup Sign up for Cerebras Get a Cerebras API Key Save it in a Val Town environment variable called CEREBRAS_API_KEY Todos I'm looking for collaborators to help. Fork & send me PRs! [ ] Experiment with two prompt chain (started here )
HTTP
/** @jsxImportSource https://esm.sh/react@18.2.0 */
import { createRoot } from "https://esm.sh/react-dom@18.2.0/client";
import { Prism as SyntaxHighlighter } from "https://esm.sh/react-syntax-highlighter";
import React, { useEffect, useState } from "https://esm.sh/react@18.2.0";
setPrompt: React.Dispatch<React.SetStateAction<string>>;
handleSubmit: (e: React.FormEvent) => void;
const previewRef = React.useRef<HTMLDivElement>(null);
async function handleSubmit(e: React.FormEvent | string) {
<React.Fragment key={iframeKey}>
</React.Fragment>
ganeshkumartk avatar
AIDateInput
@ganeshkumartk
AI Date Input AI Date Input is a smart date detection React component. It uses natural language processing to interpret various date and time inputs, providing a seamless user experience for date entry. Features Real-time date and time detection as you type Supports a wide range of date and time formats Displays detected date in a formatted output Shows both the parsed date and the original input text Clean, minimalist UI with a clear input field One-click clear functionality How It Works The AI Date Input uses the chrono-node library to parse natural language date and time expressions. As the user types, the input is continuously analyzed, and when a valid date or time is detected, it's displayed below the input field. The detected date is shown in two formats: A formatted date and time (e.g., "09/09/2024 02:27 PM") The original text that was interpreted as a date (e.g., "5 days from now") Usage To use this component in Val Town: Create a new val or edit an existing one Copy and paste the entire code into the val Save the val Access the val's URL to see the AI Date Input in action Customization You can customize the appearance and behavior of the AI Date Input: Modify the Tailwind CSS classes in the HTML to change the styling Adjust the date formatting in the formatDate function Change the parsing behavior by modifying the detectDate function Dependencies React 18 chrono-node (for date parsing) Tailwind CSS (for styling) Technical Details The component uses server-side rendering for the initial HTML Client-side JavaScript handles the interactive features Date parsing is done in real-time on the client-side Contributing To contribute to this project: Fork the val in Val Town Make your changes Test thoroughly Submit a pull request or share your modified version License This project is open-source and available under the MIT License. ©️ Ganesh Kumar 2024
HTTP
AI Date Input is a smart date detection React component. It uses natural language processing to interpret various date and ti
- React 18
- The component uses server-side rendering for the initial HTML
- Client-side JavaScript handles the interactive features
- Date parsing is done in real-time on the client-side
/** @jsxImportSource npm:react */
import { renderToString } from "npm:react-dom@18/server";
import React from "npm:react@18";
const clientScript = `
${clientScript}
granin avatar
sqliteExplorerApp
@granin
SQLite Explorer View and interact with your Val Town SQLite data. It's based off Steve's excellent SQLite Admin val, adding the ability to run SQLite queries directly in the interface. This new version has a revised UI and that's heavily inspired by LibSQL Studio by invisal . This is now more an SPA, with tables, queries and results showing up on the same page. Install Install the latest stable version (v86) by forking this val: Authentication Login to your SQLite Explorer with password authentication with your Val Town API Token as the password. Todos / Plans [ ] improve error handling [ ] improve table formatting [ ] sticky table headers [x] add codemirror [ ] add loading indication to the run button (initial version shipped) [ ] add ability to favorite queries [ ] add saving of last query run for a table (started) [ ] add visible output for non-query statements [ ] add schema viewing [ ] add refresh to table list sidebar after CREATE/DROP/ALTER statements [ ] add automatic execution of initial select query on double click [x] add views to the sidebar [ ] add triggers to sidebar [ ] add upload from SQL, CSV and JSON [ ] add ability to connect to a non-val town Turso database [x] fix wonky sidebar separator height problem (thanks to @stevekrouse) [x] make result tables scrollable [x] add export to CSV, and JSON (CSV and JSON helper functions written in this val . Thanks to @pomdtr for merging the initial version!) [x] add listener for cmd+enter to submit query
HTTP
- [ ] add refresh to table list sidebar after `CREATE/DROP/ALTER` statements
- [x] add views to the sidebar
- [ ] add triggers to sidebar
- [x] fix wonky sidebar separator height problem (thanks to @stevekrouse)
/** @jsxImportSource https://esm.sh/react */
import React, { useState, useEffect } from "https://esm.sh/react";
import { createRoot } from "https://esm.sh/react-dom/client";
window.initClient = function() {
window.initClient();
window.initClient && window.initClient();
stevekrouse avatar
pinkPig
@stevekrouse
// render WebcamPage as a client side react component with fetch handler response object
HTTP
// render WebcamPage as a client side react component with fetch handler response object
const script = `
import WebcamPage from 'https://esm.sh/gh/fal-ai/fal-js@9cc7cf5456/apps/demo-nextjs-app-router/app/camera-turbo/page.tsx';
import React from 'https://esm.sh/react@17.0.2?dev';
import { render } from 'https://esm.sh/react-dom@17.0.2?dev';
render(React.createElement(WebcamPage), document.getElementById('root'));
export default (request: Request) =>
tnorthcutt avatar
numbergame
@tnorthcutt
* This game implements a number chain puzzle where players drag between adjacent squares (including diagonals) with the same number to add up. * When a valid chain is selected, the last square in the chain holds the total value rounded up to the nearest power of two, * and the other squares get new random values. The player scores points based on the chain length and values. * We'll use React for the UI and manage game state on the client side. * The server will just serve the initial HTML and JavaScript. * * We've updated the color scheme to have a dark background with colored tiles. * Each number has its own color on a hue scale, cycling through hues for arbitrary powers of two. * Selected chain tiles now have a white border, and numbers are white for better visibility. * Non-bordered tiles now have a transparent border to maintain consistent size and prevent layout jumps. * New tiles fading in no longer show a white border. * New tiles now have a random power of two between the min and max numbers on the board. * Initial possible numbers are now between 2 and 32. * * Added error handling to prevent "TypeError: cell1 is not iterable" error.
HTTP
* and the other squares get new random values. The player scores points based on the chain length and values.
* We'll use React for the UI and manage game state on the client side.
* The server will just serve the initial HTML and JavaScript.
* Added error handling to prevent "TypeError: cell1 is not iterable" error.
/** @jsxImportSource https://esm.sh/react */
import React, { useEffect, useRef, useState } from "https://esm.sh/react";
import { createRoot } from "https://esm.sh/react-dom/client";
// Game board size
</div>
function client() {
createRoot(document.getElementById("root")).render(<App />);
if (typeof document !== "undefined") {
client();
async function server(request: Request): Promise<Response> {
vyatka avatar
uptime
@vyatka
Uptime Checker & Status Page This is a free, hackable uptime/downtime monitor that sends you an email when the site doesn't return a 200. It also stores historical uptime and latency data in your Val Town SQLite, which is used to power a status page. It supports multiple URLs in the same database and status page. Installation Edit the list of URLs to what you want to check For the status page, fork this val: @stevekrouse/status
HTTP
/** @jsxImportSource https://esm.sh/react */
import React, { useState, useEffect } from "https://esm.sh/react";
import { createRoot } from "https://esm.sh/react-dom/client";
import { sqlite } from "https://esm.town/v/stevekrouse/sqlite";
console.log(`Website down (${url}): ${reason} (${end - start}ms)`);
// Use dynamic import for sqlite to ensure server-side execution
const { sqlite } = await import("https://esm.town/v/stevekrouse/sqlite");
runUptimeChecks();
// React Frontend Component
function UptimeDashboard() {
</div>
// Client-side rendering
function client() {
createRoot(document.getElementById("root")).render(<UptimeDashboard />);
if (typeof document !== "undefined") { client(); }
// Server-side handler
export default async function server(request: Request): Promise<Response> {
stevekrouse avatar
valwriter_react_clientside
@stevekrouse
[ ] streaming we can't stream into an actual val - we can only write a full piece of text, i guess we can stream back the code so we don't get bored while we wait [ ] send the code of the valwriter back to gpt only if it's related, might need some threads [ ] send errors, logs back to gpt [ ] get screenshots of the output back to gpt [ ] experiment with applying diffs instead of regenerating from scratch every time could also have it as a conversation as the main thing and only the diffs get applied or the whole code gets replaced, maybe tool use it the key here... which does make it seem like a custom gpt may be the better fit...
HTTP
/** @jsxImportSource https://esm.sh/react@18.2.0 */
import { updateValByName } from "https://esm.town/v/nbbaier/updateValByName?v=14";
import { App } from "${import.meta.url}";
import { createRoot } from "https://esm.sh/react-dom@18.2.0/client";
import { jsx } from "https://esm.sh/react@18.2.0/jsx-runtime";
createRoot(document.body).render(jsx(App, { }));
user: "website that shows the current time",
content: `/** @jsxImportSource npm:react */
export default function() {
applemetabank avatar
sereneBeigeSheep
@applemetabank
@jsxImportSource https://esm.sh/react@18.2.0
HTTP
/** @jsxImportSource https://esm.sh/react@18.2.0 */
import React, { useState, useEffect, useRef } from "https://esm.sh/react@18.2.0";
import { createRoot } from "https://esm.sh/react-dom@18.2.0/client";
// Interfaces for robust type checking
'Real Estate'
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
</div>
function client() {
createRoot(document.getElementById("root")).render(<App />);
if (typeof document !== "undefined") { client(); }
export default async function server(request: Request): Promise<Response> {
4. Be professional, empathetic, and avoid giving direct legal recommendations
5. If the query is outside your knowledge, guide the user appropriately
Legal Categories Available: ${body.categories.join(', ')}