SpektraLab 1.3.3 · macOS · Apple silicon

Not a filter.
A print.

Open a RAW, pick a film and a paper, and get a physically modelled print — grain, halation, couplers, the enlarger's filter pack — in about a second. Light is traced through 81 wavelengths, the way a darkroom does it.

Free and open source · macOS 15 or later · Apple silicon · 30.7 MB DMG, signed and notarised

The SpektraLab window: Lower Manhattan at dusk on Kodak Portra 400, printed on Kodak Portra Endura, with the Film and Print rail on the left and the Parameters rail on the right.

Lower Manhattan on Kodak Portra 400, printed on Kodak Portra Endura — rendered live at 23 %, histogram top right.

RAW in. Print out.

Drag. That is the whole negative, printed.

On the left, the RAW as the app's Original view decodes it: same geometry, nothing cropped. On the right, the same frame developed on a film and printed on a paper. No layers, no curves — the look is the materials.

A courtyard in afternoon light, developed on Kodak Portra 400 and printed on Kodak Supra Endura.
The same courtyard as the camera's RAW decode.
RAW decode Print
Kodak Portra 400 → Kodak Supra Endura · 135

Physics, not presets

Spectral, not a LUT.

A preset is a table that moves colours. SpektraLab moves light — through the film's dye layers, then the paper's — so the look is whatever those materials do, at whatever size the negative is.

81 wavelengths, end to end

Light is traced from 380 to 780 nm in 5 nm steps, through the film's sensitivity and dye densities and then the paper's, the way an enlarger and a scanner do it. Nothing inside the engine is an RGB working space.

Physical units

Tell it the negative is 35 mm or 120 and grain, halation and coupler diffusion scale with the frame in micrometres. Call the same photograph 35 mm and its grain is coarser — correctly.

Fast enough to be a slider

A C++ Metal engine compiled into the app, no interpreter and no fallback. Print-side edits reprint from the cached negative; the full-resolution render lands under a second later.

45 MP reprint, preview size
0.01s
Full-resolution render
<1s
One binary
32MB

One colour pipeline

ProPhoto RGB from decode to export. Each file is gamut-mapped once, into the space you ask for, and soft-proofed at its own resolution before it is written. The file is the thing that does not move.

Latitude you can read

The meter says how much of the scene the film and paper hold, in stops from mid-grey — metered on the picture, never the rebate. Scene Placement pulls the rest in through the engine's own fit.

Granite cliff and sky at 1:1, showing film grain rendered per pixel.

Grain at 1:1

Grain, halation, DIR couplers and glare are stages of the process, each with its own strength — not an overlay. Each black-and-white film carries the granularity its maker publishes.

How it works

The darkroom, stage by stage.

Every control sits on the stage that owns it. Film Format, grain and halation act before development; the enlarger's filter pack and paper after; a grade only on the scan.

  1. 1Scene lightLinear RAW decode into ProPhoto
  2. 2Camera + filmSpectral exposure, latent image
  3. 3DevelopmentCharacteristic curves, DIR couplers, grain
  4. 4Enlarger + paperFilter pack solved, paper exposed
  5. 5PrintDye densities of the paper
  6. 6ScanViewed under a known light, one output transform

Films and papers

Twenty-four films. Nine papers. All measured.

Every stock is a measured profile — characteristic curves, dye spectra, coupler and halation behaviour. Choose a film and its paper comes with it; a slide film is scanned, not printed.

Colour negative

  • Kodak Portra 160
  • Portra 400
  • Portra 800
  • Portra 800 · Push 1
  • Portra 800 · Push 2
  • Ektar 100
  • Gold 200
  • UltraMax 400
  • Fujifilm C200
  • Pro 400H
  • X-Tra 400

Slide

  • Kodak Ektachrome 100
  • Kodachrome 64
  • Fujifilm Provia 100F
  • Velvia 100

Cine negative

  • Kodak Vision3 50D
  • Vision3 200T
  • Vision3 250D
  • Vision3 500T
  • Verita 200D

Black and white New in 1.3.3

  • Kodak Tri-X 400
  • T-Max 100
  • Fujifilm Neopan 100 Acros II
  • Ilford HP5 Plus 400

Papers

  • Kodak Endura Premier
  • Portra Endura
  • Supra Endura
  • Ultra Endura
  • Ektacolor Edge
  • Fujifilm Crystal Archive Type II
  • Kodak Vision 2383 cine
  • Vision Premier 2393 cine
  • Ilford Multigrade IV RC b&w
Children on a beach swing, Kodak Portra 160 on 6×6, printed on Kodak Portra Endura.
Portra EnduraPortra 160 · 6×6
Neighbours in a sunlit courtyard, Kodak Portra 400 on 135, printed on Kodak Supra Endura.
Supra EnduraPortra 400 · 135
A passer-by in front of a painted mural, Kodak Portra 400 without Film Edge, printed on Kodak Ultra Endura.
Ultra EnduraPortra 400 · no Film Edge
San Francisco across the bay at dusk, Fujifilm Pro 400H on 135, printed on Fujifilm Crystal Archive Type II.
Crystal Archive Type IIPro 400H · 135

Black and white, on Ilford Multigrade IV RC

Walt Disney Concert Hall on Fujifilm Neopan 100 Acros II, 135, printed on Ilford Multigrade IV RC.
Acros II 100 · 135Its own grain and edge print
The Grand Canyon under snow on Kodak T-Max 100, 6×9, printed on Ilford Multigrade IV RC.
T-Max 100 · 6×9Filter 2, the paper's own curve

Film and paper names are their manufacturers' trademarks, used only to identify the measured materials. SpektraLab is not affiliated with or endorsed by Kodak, Fujifilm or Ilford.

Film Edge · Date Back

The film itself.

Film Edge prints the frame on its own strip — rebate, perforations, each stock's edge print and frame numbers, measured on real strips. Date Back exposes the date, and on 120 the shooting data, into the negative the way a data back did, so they take grain and halation like everything else.

Half-frame pairs

Two frames. One piece of film.

A half-frame pair is two photographs on one frame's worth of 135, side by side or one above the other. Each hole has its own metering, white balance, print and grade; the pair is one item in the filmstrip and exports as one picture.

  • Click a hole to pick its frame — Input / Camera, Scene Placement, the Enlarger and Post-Dev then act on that frame alone.
  • Drag to move the picture under its hole; scroll or pinch to scale it about the pointer.
  • Pick two photos and press ⌘J.
SpektraLab showing a half-frame pair on Fujifilm Provia 100F: a harbour town on the left, light trails on the right, with the Half-Frame Pair section open.
A finished half-frame pair on Kodak Portra 400: birds on a railing above a pier.
Exported as one picture · Portra 400 · 135 half

Workflow

Built for the rest of the job.

Export recipes that prove the file before writing it, a clipboard that carries settings across a folder, and a command line and MCP server that drive the very same session.

The export page: a recipe list, location and naming, format and size, and an output preview of a beach swing on Kodak Portra 160.

Export recipes, soft-proofed

A recipe names a format, depth, colour space, size, naming and folder — JPEG in Display P3, 16-bit TIFF in ProPhoto, 8-bit PNG in sRGB, or a Digital Intermediate for grading elsewhere. Every file is proofed at its own resolution before it is written, pixel for pixel. Batches run one frame at a time, so a 45 MP export never needs more than one render's memory.

The Settings Clipboard: Film and Paper, Exposure, White Balance, Film Effects, Print Effects and Scene Placement, with Copy and Paste.

Settings Clipboard and Sync

Tick what travels — film and paper, exposure, white balance, film and print effects, scene placement — then copy, paste, or Sync to every selected photo. Crop, grade and film edge stay with each frame.

$ spektralab edit beach.NEF --patch '{"params":{"filmStock":"kodak_portra_400",
                                "printStock":"kodak_supra_endura"}}'
$ spektralab process beach.NEF --preview beach.jpg
$ spektralab export beach.NEF --recipe "JPEG — Display P3"
$ spektralab mcp            # serve MCP over stdio

Scriptable. Agents edit, they do not generate.

The window, spektralab and an MCP server drive the same session, so an agent can choose a film, a paper, an exposure and a grade — and never paints a pixel. Every result is a print someone could have made. Off until you turn it on in Settings ▸ Agents.

Download SpektraLab

Version 1.3.3 · 9 October 2026 · 30.7 MB

Apple silicon · macOS 15 or later · Signed with a Developer ID and notarised by Apple. Open the DMG and drag SpektraLab to Applications.

SHA-256cf548ed6b83601c468e22430302cab8839fb30f3e5352c6d07a38bf074562c6b

Windows and Linux: a Vulkan engine and a Qt Quick editor are in development on GitHub. No builds are published yet.