A small collection of SVG logos with a web UI for exporting consistently sized, padded PNGs — handy for using as Val Town val images (or any square avatar/thumbnail).
Live site: https://logo.val.run
- Stores logos as inline SVG strings, one per file.
- Shows a gallery of all logos; clicking one opens the framing tool with that logo selected.
- Provides a framing tool that wraps any logo (or Lucide icon) in a padded square canvas at a fixed pixel size, with an optional background/foreground color, and downloads it as a PNG. This is the piece that gives every exported image the same dimensions and padding.
- Open the gallery at https://logo.val.run and click the logo you want. (Or go straight to https://logo.val.run/frame and pick from the Logo dropdown.)
- Optionally switch the Source to Lucide icon and type any icon name from https://lucide.dev/icons (e.g.
heart,star,github). Lucide icons also get an Icon color control. - Adjust Size (square, in px), Padding, and Background (toggle the checkbox off for a transparent background).
- Watch the live preview, then click Download PNG.
- Upload the resulting PNG as your val's image.
Keeping Size and Padding the same across exports is what makes the logos look consistent when used as val images.
The app is a Hono HTTP handler in http.tsx. Routes:
| Route | Description |
|---|---|
/ | Gallery of all logos; each card links to /frame?logo=<name>. |
/frame | Interactive framing tool (UI). Accepts ?logo=<name> to preselect a logo. |
/frame.png?... | Rendered framed PNG (see query params below). |
/:name | Raw logo as SVG (direct access), e.g. /github. |
/:name.png | Raw logo as PNG (direct access), e.g. /github.png. |
/lucide/:name | A Lucide icon as raw SVG (used by the preview). |
/source | Redirects to the val source. |
You can build a download link directly without the UI. Provide either logo or lucide:
| Param | Default | Notes |
|---|---|---|
logo | — | Name of a built-in logo, e.g. github. |
lucide | — | Name of a Lucide icon, e.g. heart. |
size | 1024 | Output width/height in px (clamped 64–4096). |
padding | 64 | Space between the canvas edge and the logo (clamped 0 … size/2 − 1). |
bg | transparent | Background color, or transparent. Any CSS color. |
color | — | Foreground color for currentColor-based icons (Lucide). |
Examples:
# Built-in logo, 1024px, white background
https://logo.val.run/frame.png?logo=github&size=1024&padding=128&bg=%23ffffff
# Lucide icon, transparent background, custom icon color
https://logo.val.run/frame.png?lucide=heart&size=1024&padding=160&bg=transparent&color=%23e11d48
Each logo lives in its own file that exports a named SVG string, which http.tsx imports and registers.
-
Create a file, e.g.
mylogo.http.tsx(an.http.tsxfile also gives you a standalone endpoint for that logo, but any.tsxthat exports the SVG works). -
Export the SVG as a named constant. The framing tool rescales whatever
viewBox(or width/height) you provide, so keep the markup clean:export const mylogo = ` <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <!-- paths here --> </svg> `;Tip: SVGs that use
stroke="currentColor"orfill="currentColor"will pick up the frame's color option — that's how Lucide icons are recolored. -
Register it in
http.tsx:import { mylogo } from "./mylogo.http.tsx"; const logos: Record<string, string> = { // ...existing entries mylogo, };
That's it — the logo now appears in the gallery, at /mylogo, /mylogo.png, and in the /frame picker.
frame.tsx exports buildFrameSvg(logoSvg, opts), shared by the server (/frame.png) and mirrored client-side in the /frame preview so the on-screen render matches the download. It:
- parses the source SVG's
viewBox(falling back to width/height), - centers it inside a
size × sizecanvas with the givenpaddingusingpreserveAspectRatio="xMidYMid meet", - preserves presentation attributes (
stroke,stroke-width,fill, …) so icons keep their styling, - optionally draws a background
<rect>and applies acolorvia a wrapping<g>forcurrentColor.
PNGs are rasterized from that SVG with resvg_wasm.
| File | Role |
|---|---|
http.tsx | Main HTTP entrypoint (gallery, /frame, /frame.png, per-logo routes). |
frame.tsx | Shared buildFrameSvg helper for the padded square canvas. |
render.tsx | Small helper that turns a logo SVG into a per-file HTTP handler (/, /.png). |
lucide.tsx | Fetches Lucide icon SVGs on demand from lucide-react. |
*.http.tsx / *.tsx (logos) | Individual logos, each exporting a named SVG string. |