✳ OMNIVIEWER / share by URL — live examples

Share a file by URL — the link is the file

no upload · no server · no expiry · no account · works offline once loaded

Every link on this page carries a complete file inside its #payload= fragment: base64url-encoded bytes that OmniViewer decodes locally, in your browser. Because the payload lives in the URL fragment (the part after #), it is never sent to any server — it does not appear in server logs, caches or analytics. There is nothing to delete later, nothing that expires, and nothing anyone else can take down: whoever has the link has the file.

How a share link works

The anatomy of a share URL:

https://omniviewer.org/json/hex#payload=<base64url bytes>&encoding=base64&name=notes.json

To make your own: open or type any content up to 32 KB in OmniViewer and press the link action in the toolbar — the share URL lands in your clipboard and address bar. Links up to 8 MB of fragment (1 MB decoded) load fine; the 32 KB cap only limits what the app offers to create, keeping URLs practical to paste. The decoded payload goes through exactly the same pipeline as a dropped file, so a shared file behaves — and is sandboxed — like any other untrusted file.

JavaScript

Five snippets that exercise the whole /js toolkit: the formatted view, the compressor, the deobfuscator, the obfuscator and the stats report. Each link lands directly on the tab named in its URL path (/js/stats, /js/compressor, …).

hello.js — Hello world, syntax-highlighted

149 bytes in the fragment · opens the FORMAT tab

A three-line greeting. Opens straight on the FORMATTED tab: reflowed, coloured, line-numbered.

// Your code travels inside the link itself — no server ever sees it.
const greet = (name) => `Hello, ${name}!`;
console.log(greet('OmniViewer'));

Open hello.js in OmniViewer →

fizzbuzz.js — FizzBuzz, opened on the STATS tab

144 bytes in the fragment · opens the STATS tab

The classic loop, landing on code statistics: keyword distribution, lines of code, function counts.

for (let i = 1; i <= 100; i++) {
  let out = '';
  if (i % 3 === 0) out += 'Fizz';
  if (i % 5 === 0) out += 'Buzz';
  console.log(out || i);
}

Open fizzbuzz.js in OmniViewer →

minified.js — Minified one-liner → deobfuscator

113 bytes in the fragment · opens the DEOBFUSCATOR tab

A squeezed Fibonacci one-liner that the DEOBFUSCATOR lays back out into readable, indented source.

const f=n=>{let a=0,b=1;while(n-->0){[a,b]=[b,a+b]}return a};console.log([...Array(10).keys()].map(f).join(","));

Open minified.js in OmniViewer →

chatty.js — Over-commented class → compressor

677 bytes in the fragment · opens the COMPRESSOR tab

An event emitter with far too many comments. The COMPRESSOR strips them and shows the size win.

// A tiny event emitter, commented far beyond its pay grade.
// Every listener lives in a Map from event name to a Set of callbacks.
class Emitter {
  constructor() {
    // The registry: event name -> Set of listeners.
    this.listeners = new Map();
  }
  // Subscribe. Returns a function that unsubscribes again.
  on(event, fn) {
    if (!this.listeners.has(event)) this.listeners.set(event, new Set());
    this.listeners.get(event).add(fn);
    return () => this.listeners.get(event)?.delete(fn);
  }
  // Fire every listener registered for this event, in insertion order.
  emit(event, payload) {
    for (const fn of this.listeners.get(event) ?? []) fn(payload);
  }
}

Open chatty.js in OmniViewer →

greeting.js — String literals → obfuscator

136 bytes in the fragment · opens the OBFUSCATOR tab

Plain code with readable strings. The OBFUSCATOR minifies it and rewrites the strings as \x hex escapes.

const password = 'correct horse battery staple';
const banner = 'Welcome to the obfuscator demo';
console.log(banner, password.length);

Open greeting.js in OmniViewer →

JSON

JSON files get the full /json toolkit: a pretty-printed, syntax-highlighted Formatted view, one-click conversion to YAML and (for arrays of objects) CSV, and a Stats report — plus the raw and hex views. Each link lands on the tab named in its URL path (/json/csv, /json/hex, …).

package.json — A package.json manifest, formatted

266 bytes in the fragment · opens the FORMATTED tab

A typical npm manifest, landing on the FORMATTED tab: pretty-printed, syntax-highlighted and line-numbered.

{
  "name": "shared-by-url",
  "version": "1.0.0",
  "description": "This file arrived through the URL fragment — no upload involved.",
  "type": "module",
  "scripts": { "start": "node index.js" },
  "keywords": ["share", "url", "fragment"],
  "license": "MIT"
}

Open package.json in OmniViewer →

earthquake.geojson — GeoJSON point feature

172 bytes in the fragment

A GeoJSON Feature with coordinates and properties, shared as a link instead of an attachment.

{
  "type": "Feature",
  "geometry": { "type": "Point", "coordinates": [-122.4194, 37.7749] },
  "properties": { "mag": 4.2, "place": "San Francisco, CA", "tsunami": 0 }
}

Open earthquake.geojson in OmniViewer →

api-response.json — API response, opened in hex

103 bytes in the fragment · opens the HEX tab

A compact API payload landing on the HEX tab — offsets, bytes and the ASCII column side by side.

{"ok":true,"data":{"users":[{"id":1,"name":"Ada"},{"id":2,"name":"Linus"}],"total":2},"ts":1751808000}

Open api-response.json in OmniViewer →

people.json — Array of objects → CSV table

229 bytes in the fragment · opens the CSV tab

A list of records. Because it’s an array of objects, the CSV tab appears and flattens it to a table — the header is the union of every object’s keys.

[
  { "id": 1, "name": "Ada Lovelace", "role": "engineer", "active": true },
  { "id": 2, "name": "Alan Turing", "role": "researcher", "active": true },
  { "id": 3, "name": "Grace Hopper", "role": "admiral", "active": false }
]

Open people.json in OmniViewer →

config.json — Nested config → YAML

162 bytes in the fragment · opens the YAML tab

A nested configuration object, landing on the YAML tab: the same data as a block-style YAML document you can copy or download.

{
  "service": "omniviewer",
  "port": 4173,
  "features": { "hex": true, "share": true, "upload": false },
  "hosts": ["omniviewer.org", "dev.omniviewer.org"]
}

Open config.json in OmniViewer →

metrics.json — Daily metrics → STATS

171 bytes in the fragment · opens the STATS tab

Three days of counters, opened on STATS: value/type distribution, nesting depth, total and unique keys, and the most frequent keys.

[
  { "day": "2026-07-01", "views": 1204, "shares": 37 },
  { "day": "2026-07-02", "views": 1580, "shares": 52 },
  { "day": "2026-07-03", "views": 1990, "shares": 61 }
]

Open metrics.json in OmniViewer →

CSV

CSV files get the full /csv toolkit: a column-aligned Formatted table, one-click conversion to JSON, an in-browser SQL engine over a table called data, and per-column Stats — plus the raw and hex views. Each link lands on the tab named in its URL path (/csv/json, /csv/sqlite).

people.csv — Rows → a JSON array of objects

108 bytes in the fragment · opens the JSON tab

A tiny CSV, opened on JSON: each row becomes an object keyed by the header, with numbers and booleans typed, syntax-highlighted and ready to copy.

id,name,role,active
1,Ada Lovelace,engineer,true
2,Alan Turing,researcher,true
3,Grace Hopper,admiral,false

Open people.csv in OmniViewer →

sales.csv — Query it with SQL

103 bytes in the fragment · opens the SQLITE tab

Four months of sales, streamed into an in-browser SQLite table called data. Land on the SQLITE tab and run SELECT * FROM data — or sum the revenue — with no upload.

month,units,revenue
2026-01,120,15400.50
2026-02,98,12210.00
2026-03,143,18990.75
2026-04,131,17240.20

Open sales.csv in OmniViewer →

Rust

OmniViewer has no Rust-specific tooling (yet) — these show the universal path: any text file gets a numbered raw view and a hex view, whatever the extension.

hello.rs — Hello world in Rust

58 bytes in the fragment

The smallest Rust program, shared by URL. Line numbers come from the text sniff, not the extension.

fn main() {
    println!("Hello from a URL fragment!");
}

Open hello.rs in OmniViewer →

fibonacci.rs — Recursive Fibonacci with match

196 bytes in the fragment

Pattern matching, ranges and an iterator chain — a small but idiomatic slice of Rust.

fn fib(n: u64) -> u64 {
    match n {
        0 | 1 => n,
        _ => fib(n - 1) + fib(n - 2),
    }
}

fn main() {
    let seq: Vec<u64> = (0..10).map(fib).collect();
    println!("{seq:?}");
}

Open fibonacci.rs in OmniViewer →

traits.rs — A trait and its impl

234 bytes in the fragment

Trait definition, a struct and an impl block: enough Rust to argue about in a code review link.

trait Greet {
    fn greet(&self) -> String;
}

struct Viewer;

impl Greet for Viewer {
    fn greet(&self) -> String {
        "every byte stays in your browser".to_string()
    }
}

fn main() {
    println!("{}", Viewer.greet());
}

Open traits.rs in OmniViewer →

Plain text & data

Notes, Markdown, logs and CSV — the everyday snippets you’d otherwise paste into a chat as a screenshot.

notes.txt — Plain-text note with UTF-8

167 bytes in the fragment

Emoji and em dashes round-trip byte-for-byte: the fragment carries the exact UTF-8 bytes.

Shopping list — shared straight through a URL:

  - coffee ☕
  - rye bread
  - 1 kg oranges

The em dash and the emoji above prove UTF-8 survives the trip intact.

Open notes.txt in OmniViewer →

README.md — A Markdown README

324 bytes in the fragment

Markdown is text, so it gets line numbers and the stats-friendly raw view.

# Shared via URL

This markdown file was never uploaded anywhere.

1. The bytes are base64url-encoded into the link's `#payload=` fragment.
2. Fragments never leave the browser — servers and logs never see them.
3. OmniViewer decodes the fragment locally and shows the file.

*Share small files with zero infrastructure.*

Open README.md in OmniViewer →

server.log — A server log snippet

348 bytes in the fragment

Five log lines you can hand to a colleague as a URL — no pastebin, no retention policy, no server.

2026-07-06T09:00:01Z INFO  boot        omniviewer static site up
2026-07-06T09:00:04Z INFO  ingest      file received via #payload= fragment
2026-07-06T09:00:04Z DEBUG sniff       verdict=text lines=6
2026-07-06T09:00:05Z WARN  upload      no upload endpoint exists — nothing to do
2026-07-06T09:00:05Z INFO  done        rendered locally in 3 ms

Open server.log in OmniViewer →

data.csv — A small CSV table

117 bytes in the fragment

City populations in CSV. For huge CSVs use hugecsv.com; for a quick shared snippet, this is enough.

city,country,population
Tokyo,Japan,37400068
Delhi,India,28514000
Shanghai,China,25582000
São Paulo,Brazil,21650000

Open data.csv in OmniViewer →

Images

Binary payloads round-trip byte-for-byte, so a real PNG and the famous 43-byte GIF arrive intact — magic numbers, checksums and all. SVG, being XML, arrives as readable text.

pixel-heart.png — An 8×8 PNG heart, in hex

105 bytes in the fragment · opens the HEX tab

A real, valid PNG built byte-by-byte. The hex view opens on the 89 50 4E 47 magic — “‰PNG” — followed by IHDR, IDAT and IEND chunks.

00000000  89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52  .PNG........IHDR
00000010  00 00 00 08 00 00 00 08 08 02 00 00 00 4B 6D 29  .............Km)
… 105 bytes total

Open pixel-heart.png in OmniViewer →

smallest.gif — The 43-byte GIF, in hex

43 bytes in the fragment · opens the HEX tab

The famous smallest-possible GIF: header, one-entry colour table, and a single transparent pixel — all 43 bytes visible at once.

00000000  47 49 46 38 39 61 01 00 01 00 80 00 00 00 00 00  GIF89a..........
00000010  FF FF FF 21 F9 04 01 00 00 00 00 2C 00 00 00 00  ...!.......,....
… 43 bytes total

Open smallest.gif in OmniViewer →

logo.svg — An SVG logo as text

275 bytes in the fragment

SVG is XML, so the raw view shows the markup itself — shapes, strokes and fills as readable source.

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="32" height="32">
  <rect width="32" height="32" rx="6" fill="#0d1117"/>
  <circle cx="16" cy="16" r="9" fill="none" stroke="#4da3ff" stroke-width="3"/>
  <circle cx="16" cy="16" r="3" fill="#7fbf7f"/>
</svg>

Open logo.svg in OmniViewer →

WebAssembly

Two genuinely valid .wasm modules small enough to live in a URL. Wasm has no toolkit route (yet), so these land on the raw view — the HEX tab is the natural next click: magic, version, then the sections.

add.wasm — A 41-byte WebAssembly module

41 bytes in the fragment · HEX one click away

A complete, valid wasm module exporting add(a, b). Open the HEX tab and it starts at the 00 61 73 6D magic — “\0asm”.

00000000  00 61 73 6D 01 00 00 00 01 07 01 60 02 7F 7F 01  .asm.......`....
00000010  7F 03 02 01 00 07 07 01 03 61 64 64 00 00 0A 09  .........add....
… 41 bytes total

Open add.wasm in OmniViewer →

empty.wasm — The smallest valid wasm module

8 bytes in the fragment · HEX one click away

Eight bytes: the \0asm magic plus version 1. WebAssembly.validate() says yes; the HEX tab shows why.

00000000  00 61 73 6D 01 00 00 00                          .asm....

Open empty.wasm in OmniViewer →

More questions?

The OmniViewer FAQ covers file-size limits, privacy and the format-specific tools. For huge files, drag and drop is the way — share links are for the small stuff you’d otherwise paste into a chat.