Skip to study
EW Studio

2021 → 2026 / Pixe

A light table for creative direction.

Built around a board rather than another wall of search results.

Role
Product, design direction and engineering lead, built with Claude Code
Timeline
2021 original · rebuilt 19–25 October 2026
Stack
React 19 · TypeScript · TanStack Router · IndexedDB

Live example-board recording. Photographer, Unsplash, Pexels and Openverse source/licence links remain part of the app interface. Public-stock search and user uploads have different AI boundaries. Photographer and licence links for the captured prints.

Capture actions, source links and limits

See the phone layoutPixe live phone interface at 390 pixels wide
202 pending

Slow-source search returns after 20 seconds; the separate board-build wait ends at 12 seconds.

The rebuild

Keep the spark.
Rebuild the product.

2021 → 2026

Pixe began in 2021 as a React 17 photo search: type a word, get 30 Unsplash photos in a masonry grid. It had the Unsplash key in the source, no alt text (alt={discription}), and no credit for photographers. It also can't be rebuilt as it was: Unsplash's API rules say an app may not replicate Unsplash's core experience.

Reconstructed from the archived original source with React 18, esbuild and Dart Sass; the original CRA 4/node-sass toolchain was not rebuilt. Old Unsplash calls are disabled and the exposed key is removed; the empty search is authentic to that offline state. Revision and substitutions

2021 source reconstruction → live 2026 product. Same 1440 × 900 viewport, uncropped. Historical layout rendered with compatibility tooling; it does not demonstrate the old services working.

Pixe, live 2026 interface
2026 / live product
Pixe, 2021 source reconstruction
2021 / reconstruction

The idea

A board, not an image-search clone.

Instrument Serif, warm black and lime frame actual prints on a light table. Rulers and specification lines support a working board rather than decorating a search grid.

Pixe

Instrument Serif / original SVG mark

Lime / #D4FF3AWarm black / #0E0D0C

Brand colours above; text and focus accents adapt for contrast in each portfolio theme. Design source ↗

Three engineering decisions

The constraint shapes
the implementation.

Design around source rules

Constraint. Repeating Unsplash's core experience is prohibited by the documented guidelines; the old app exposed its key

Decision. make search a tool inside a board, proxy keys and normalize sources, hotlink returned URLs and report exports

Result. a moodboard with credit and licence context. Searches cache for one hour; the documented shared source budgets are 200/day for anonymous Openverse and 50/hour for Unsplash demo.

Source and evidence limits

pixe/README.md → “Not an Unsplash clone”, “The keys stay on the server”. No claim that Openverse checks every licence.

Read the pinned README ↗

Let slow sources finish outside the request

Constraint. Openverse can take 40 seconds, beyond Heroku's 30-second limit

Decision. return 202 pending after 20 seconds, let the in-flight search fill the cache and poll again

Result. fast-source results appear immediately; board creation excludes a still-loading source after 12 seconds.

Source and evidence limits

pixe/README.md → “Slow sources don't hold the page, or break it”. Explain the separate search and board-build clocks; do not imply a 40-second HTTP response survives the router.

Read the pinned README ↗

Keep the canvas in the DOM

Constraint. Pixel canvas content is hard for screen readers to inspect and tldraw has a commercial licence constraint

Decision. real elements in one transformed layer, alt text, tab/arrow controls and an equivalent list

Result. pointer drag, resize, pan and zoom in about 350 lines, with a nonvisual reading path.

Source and evidence limits

pixe/README.md → “A DOM canvas, not a <canvas>”. “About” is essential; this is README-reported implementation size, not an accessibility audit score.

Read the pinned README ↗

Architecture

Follow one request.

Board01Photo search02Source adapters03Credited CDN04DOM prints05BoardPhoto searchSource adaptersCredited CDNDOM prints
The board calls shared cached photo adapters; credited images load from source CDNs into DOM prints. Palette extraction is local. AI description accepts selected public stock URLs only; uploaded images never enter the free-tier model. Board data remains in IndexedDB.

Quality proof / evidence, with scope

Show what was checked.

App evidence

README reports Lighthouse ≥95 and zero axe violations.

Repository report, read 26 October 2026. These app scores were not rerun for this portfolio.

Commands and evidence in the README ↗

This portfolio page

Static HTML, deferred decorative Stage, explicit media intent and complete reduced-motion content.

performance
97/100
accessibility
100/100
best practices
100/100
seo
100/100

Lighthouse mobile, light theme, cold cache, simulated throttling. Measured 2026-10-26. Gzip static export on localhost.

Eight page cases across Chromium/WebKit, phone/desktop and both themes; two axe audits with zero violations. WebKit playback and real Safari hardware remain unverified.

Read the dated portfolio check results ↗

The honest next step

What remains.

Existing boards open without the API, but search does not. Offline search is a possible improvement, not a shipped feature.

Next / Translate+Say it like you mean it. ← Back to studio index