silvia-odwyer/photon
⚡ Rust/WebAssembly image processing library
Healthy across the board
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit today
- ✓24+ active contributors
- ✓Distributed ownership (top contributor 45% of recent commits)
Show all 6 evidence items →Show less
- ✓Apache-2.0 licensed
- ✓CI configured
- ✓Tests present
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/silvia-odwyer/photon)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/silvia-odwyer/photon on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: silvia-odwyer/photon
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/silvia-odwyer/photon shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit today
- 24+ active contributors
- Distributed ownership (top contributor 45% of recent commits)
- Apache-2.0 licensed
- CI configured
- Tests present
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live silvia-odwyer/photon
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/silvia-odwyer/photon.
What it runs against: a local clone of silvia-odwyer/photon — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in silvia-odwyer/photon | Confirms the artifact applies here, not a fork |
| 2 | License is still Apache-2.0 | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 30 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of silvia-odwyer/photon. If you don't
# have one yet, run these first:
#
# git clone https://github.com/silvia-odwyer/photon.git
# cd photon
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of silvia-odwyer/photon and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "silvia-odwyer/photon(\\.git)?\\b" \\
&& ok "origin remote is silvia-odwyer/photon" \\
|| miss "origin remote is not silvia-odwyer/photon (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is Apache-2.0" \\
|| miss "license drift — was Apache-2.0 at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "crate/src/lib.rs" \\
&& ok "crate/src/lib.rs" \\
|| miss "missing critical file: crate/src/lib.rs"
test -f "crate/src/filters.rs" \\
&& ok "crate/src/filters.rs" \\
|| miss "missing critical file: crate/src/filters.rs"
test -f "crate/src/adjustments.rs" \\
&& ok "crate/src/adjustments.rs" \\
|| miss "missing critical file: crate/src/adjustments.rs"
test -f "crate/src/effects.rs" \\
&& ok "crate/src/effects.rs" \\
|| miss "missing critical file: crate/src/effects.rs"
test -f "crate/Cargo.toml" \\
&& ok "crate/Cargo.toml" \\
|| miss "missing critical file: crate/Cargo.toml"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 30 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~0d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/silvia-odwyer/photon"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Photon is a high-performance Rust/WebAssembly image processing library that compiles to both native binaries and browser-ready WASM, enabling identical image manipulation code to run at near-native speed on the web, Node.js, and natively. It provides filters, effects, color space conversions, convolution operations, and content-aware transformations (seam carving) with 100% Rust implementation for memory safety. Monorepo structure: crate/src/ contains modular Rust source split by operation type (adjustments.rs, effects.rs, filters.rs, colour_spaces.rs, conv.rs, corrections.rs, monochrome.rs, channels.rs, transform.rs, text.rs, noise.rs), with crate/examples/ providing runnable demos and test images; separate crate/benches/photon_benchmark.rs for performance regression testing.
👥Who it's for
Web developers building image editors or photo apps who need performant client-side image processing without native dependencies; Rust developers creating cross-platform desktop/CLI photo applications; Node.js developers wanting WASM-accelerated image operations without C/C++ bindings.
🌱Maturity & risk
Production-ready: active development with CI/CD pipelines (.github/workflows/ci.yml and compile_wasm.yaml), published on crates.io and npm (@silvia-odwyer/photon), benchmarks available, and structured changelogs. The monorepo structure with crate/ subdirectory and examples/ with real test images suggests stability, though single-maintainer governance (silvia-odwyer) means watch for velocity.
Moderate risk: primarily single-maintainer project (silvia-odwyer), no lock file visible in top-level directory suggesting potential dependency drift, WASM build output in docs/ indicates CI artifacts aren't .gitignored—check for stale deployments. Rust ecosystem is stable but WASM toolchain versioning (wasm-bindgen) can break builds; verify Cargo.toml pins.
Active areas of work
Unable to determine from provided metadata—check recent commits on master branch and GitHub Actions runs in .github/workflows/ for latest CI status. CHANGELOG.md exists but content not shown; inspect it and GitHub releases tab for version history and planned work.
🚀Get running
git clone https://github.com/silvia-odwyer/photon && cd photon && cd crate && cargo build --release. For WASM: cargo build --target wasm32-unknown-unknown --release (requires wasm-pack toolchain). For examples: cargo run --example example (from crate/ directory).
Daily commands: From crate/ directory: cargo run --example example for native execution. For WASM dev: wasm-pack build --target web (requires Node.js + wasm-pack). For native CLI: cargo build --bin bin (src/bin/bin.rs), then ./target/release/photon (exact CLI args depend on bin.rs implementation).
🗺️Map of the codebase
crate/src/lib.rs— Main library entry point exposing the public API; defines all module exports and wasm-bindgen bindings that bridge Rust to WebAssembly.crate/src/filters.rs— Core image filtering functionality including convolution kernels and filter implementations; heavily used by nearly all image processing operations.crate/src/adjustments.rs— Color and tone adjustments (brightness, contrast, saturation); foundational for most user-facing image modifications.crate/src/effects.rs— Visual effects and artistic transformations; demonstrates the library's capability to apply complex pixel-level operations.crate/Cargo.toml— Defines all dependencies including wasm-bindgen and image format support; critical for understanding build configuration and external constraints.crate/src/native.rs— Performance-critical native/SIMD operations for pixel manipulation; handles raw buffer operations underlying high-performance filters..github/workflows/compile_wasm.yaml— WebAssembly compilation pipeline; shows how Rust code is built for browser deployment and NPM distribution.
🛠️How to make changes
Add a new filter or effect
- Implement the filter function in crate/src/filters.rs or crate/src/effects.rs following the pattern: pub fn filter_name(photon_image: &mut PhotonImage) -> PhotonImage (
crate/src/filters.rs) - Export the function in crate/src/lib.rs with #[wasm_bindgen] macro so it's callable from JavaScript (
crate/src/lib.rs) - Add tests in crate/src/tests.rs to verify pixel transformations work correctly (
crate/src/tests.rs) - If using convolution, implement or reuse kernels from crate/src/conv.rs (
crate/src/conv.rs)
Add a new color space conversion
- Add conversion functions to crate/src/colour_spaces.rs following patterns like fn rgb_to_hsl(r: u8, g: u8, b: u8) -> (f32, f32, f32) (
crate/src/colour_spaces.rs) - Export public functions from crate/src/lib.rs with #[wasm_bindgen] if needed for direct JS access (
crate/src/lib.rs) - Use helpers in crate/src/helpers.rs for common math operations like min/max/delta calculations (
crate/src/helpers.rs)
Optimize a hot code path with SIMD
- Identify the performance-critical function and create a native implementation in crate/src/native.rs using packed_simd or inline assembly (
crate/src/native.rs) - Call the native function from the higher-level function in filters.rs or effects.rs, falling back to scalar code if SIMD unavailable (
crate/src/filters.rs) - Run benchmarks in crate/benches/photon_benchmark.rs to measure improvement (
crate/benches/photon_benchmark.rs)
Add a new image transformation (rotate, scale, etc.)
- Implement transformation logic in crate/src/transform.rs, modifying pixel coordinates and applying interpolation as needed (
crate/src/transform.rs) - Export with #[wasm_bindgen] in crate/src/lib.rs so JavaScript can call pub fn transform_name(photon_image: &PhotonImage, param: type) -> PhotonImage (
crate/src/lib.rs) - Create an example in crate/examples/ showing before/after (e.g., crate/examples/rotate.rs pattern) (
crate/examples/rotate.rs)
🔧Why these technologies
- Rust + wasm-bindgen — Provides memory-safe image processing with zero-cost abstractions; compiles to WebAssembly for browser execution with minimal overhead compared to JavaScript
- WebAssembly (wasm32-unknown-unknown) — Enables high-performance image processing in browsers without native plugins; packages distribute via NPM for seamless JavaScript integration
- Convolution kernels (filters.rs, conv.rs) — Standard foundation for all spatial filtering operations (blur, edge detection, sharpening); highly parallelizable
- Color space conversions (colour_spaces.rs) — Necessary for hue/saturation adjustments and various artistic effects; enables operations in perceptually-uniform spaces like HSL/LAB
- Content-aware seam carving (transform.rs) — Implements intelligent image resizing that preserves important features; demonstrates advanced algorithm beyond simple pixel operations
⚖️Trade-offs already made
-
Allocate new PhotonImage for most operations instead of in-place mutation
- Why: Simplifies API and reduces lifetime complexity for WASM boundaries; easier for JavaScript consumers to reason about
- Consequence: Higher memory usage during processing; images must be copied. Mitigated by garbage collection but impacts performance on constrained devices
-
Pure scalar Rust in most filters, opt-in SIMD in native.rs
- Why: Maximizes portability across CPU architectures and WebAssembly runtimes; SIMD intrinsics not universally supported
- Consequence: Leaves performance on the table for platforms with strong SIMD support (x86_64, ARM NEON); developers must explicitly optimize hot paths
-
Single-threaded execution within WASM context
- Why: WASM workers are complex; keeps deployment simple and dependency-light for end-users
- Consequence: Cannot leverage multiple CPU cores within a single image operation; large images may block the main thread
-
Expose PhotonImage as the primary abstraction (wrapper around Vec<u8>)
- Why: Clear, simple API boundary for WASM; familiar to users of image crates
- Consequence: Requires serialization to/from JavaScript ImageData/Uint8Array on every boundary crossing; potential performance tax on frequent small operations
🚫Non-goals (don't propose these)
- Real-time video processing (no frame buffering or streaming architecture)
- GPU acceleration (pure CPU/WASM, no WebGL/WebGPU integration)
- Machine learning-based operations (no neural networks or tensor operations)
- Distributed/batch processing (single-machine library, not a service)
- Platform-specific optimizations (not a cross-platform desktop app)
- Lossy compression or codec implementation (uses existing format libraries, doesn't implement codecs)
🪤Traps & gotchas
WASM target requires wasm-pack toolchain (cargo install wasm-pack); standard cargo build will fail without --target wasm32-unknown-unknown. Pixel data assumed RGBA 8-bit in most functions—grayscale or other formats need channel conversion first. crate/src/native.rs uses unsafe {} blocks: modifying without understanding SIMD alignment can cause silent data corruption. Browser WASM size matters: check docs/ .js.map files to understand bundle bloat from examples. Documentation generation requires rustdoc; run cargo doc --open from crate/ directory.
🏗️Architecture
💡Concepts to learn
- WebAssembly (WASM) compilation targets — Understanding wasm32-unknown-unknown vs wasm32-wasi and wasm-bindgen's role is critical to debugging browser vs Node deployments and memory layout differences
- Convolution operations (filters.rs core) — Blur, sharpen, edge detection all use kernel convolution; understanding stride, padding, and separable kernels unlocks filter optimizations and new filter creation
- Seam carving (content-aware resizing) — crate/examples/seam_carver.rs implements dynamic programming for aspect-ratio-preserving resizing; demonstrates non-trivial algorithm integration beyond simple pixel ops
- Color space transformations (RGB↔HSL, CMYK, LAB) — crate/src/colour_spaces.rs handles perceptual color operations; necessary for effects like hue rotation and color-space-aware filters that fail in RGB alone
- SIMD and vectorization in unsafe blocks — crate/src/native.rs contains alignment-critical unsafe {} for performance; incorrectly vectorized pixel operations cause silent data corruption
- Dithering algorithms (monochrome.rs) — Floyd-Steinberg and other dithering reduce banding in posterized/quantized images; understanding error diffusion is key to 1-bit/indexed color output
- wasm-bindgen macro system — The #[wasm_bindgen] attribute defines which Rust functions expose to JavaScript with automatic type conversion; misused attributes cause WASM runtime panics
🔗Related repos
image-rs/image— Pure Rust image codec and basic processing library; Photon likely depends on this for file I/O and pixel format conversionsgfx-rs/wgpu— GPU-accelerated graphics in Rust/WASM; alternative for WebGL-backed image processing when CPU WASM is insufficientrustwasm/wasm-bindgen— Core infrastructure for Rust-to-JS interop used throughout Photon's WASM API layercloudinary/cloudinary_js— Commercial image processing SaaS; Photon is local-first alternative enabling browser-side manipulation without server uploadsfluent-ffmpeg/node-fluent-ffmpeg— Node.js video processing; Photon handles still frames while ffmpeg handles video—complementary for media pipelines
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive unit tests for crate/src/text.rs module
The text.rs module handles font rendering and text operations, but crate/src/tests.rs appears minimal. Given that the repo includes font files (Roboto-Black.ttf, Roboto-Regular.ttf), there should be specific tests validating text rendering with different fonts, sizes, and edge cases. This is critical for a visual library where text functionality affects output.
- [ ] Create test cases in crate/src/tests.rs or a dedicated text_tests.rs module
- [ ] Add tests for font loading with the included Roboto fonts in crate/fonts/
- [ ] Test text rendering at various sizes and positions
- [ ] Add regression tests using the example images in crate/examples/input_images/ as reference outputs
- [ ] Document expected behavior in crate/examples/README.md
Add benchmark comparisons in crate/benches/photon_benchmark.rs for transform.rs operations
The repo contains multiple transform operations (rotate, shear, seam_carver examples exist), but the benchmark file only has one entry point. Performance comparisons between different transformation algorithms would help contributors optimize and track regressions. This is especially important for WebAssembly performance.
- [ ] Expand crate/benches/photon_benchmark.rs to include benchmarks for crate/src/transform.rs functions
- [ ] Add benchmarks comparing rotate.rs, shear.rs, and seam_carver.rs examples against the benchmark suite
- [ ] Include memory allocation profiling since WASM has stricter constraints
- [ ] Document benchmark results in crate/examples/README.md with performance expectations
Create GitHub Actions workflow to validate WASM build reproducibility and size tracking
The repo has .github/workflows/compile_wasm.yaml but no workflow tracking WASM binary sizes or validating reproducible builds. Given the WebAssembly focus and monthly NPM downloads, tracking artifact sizes and build consistency is critical for releases. This prevents unexpected bloat.
- [ ] Create .github/workflows/wasm_size_check.yml to run on PRs
- [ ] Add size comparison between current and previous builds (target .module.wasm files in docs/)
- [ ] Integrate cargo-bloat or wasm-opt to detect size regressions
- [ ] Store baseline metrics in .github/ directory or repository metadata
- [ ] Update SECURITY.md with WASM artifact verification procedures
🌿Good first issues
- Add unit tests to crate/src/monochrome.rs and crate/src/noise.rs—currently no visible test functions for grayscale/dithering operations and noise generation; start with round-trip validation (apply then verify).
- Document WASM function signatures in crate/src/lib.rs—#[wasm_bindgen] macros lack JSDoc comments; add doc comments explaining parameter types (PhotonImage, u32 for pixel data) visible in generated npm package.
- Add seam carving example to crate/examples/ alongside existing rotate.rs and shear.rs—crate/examples/seam_carver.rs exists but is unused; create runnable demo with before/after image output and usage documentation.
⭐Top contributors
Click to expand
Top contributors
- @silvia-odwyer — 45 commits
- @volbot — 17 commits
- @benliao — 7 commits
- @advancedtw — 5 commits
- @edo-zhou — 3 commits
📝Recent commits
Click to expand
Recent commits
7779cc3— Merge pull request #214 from berkertopuz59/fundamental-functions (silvia-odwyer)2c2c5bb— Run cargo fmt - remaining files (silvia-odwyer)f4adfe3— cargo fmt (silvia-odwyer)09fc5a0— Merge remote-tracking branch 'origin/master' into fundamental-functions (silvia-odwyer)ab6ed9c— Merge pull request #216 from CanerFk/master (silvia-odwyer)3d9be97— feat: implement bayer dither, film grain, and vignette (closes #215) (CanerFk)65605f9— Merge pull request #212 from edo-zhou/chore/demo (silvia-odwyer)0dd3ad8— Merge pull request #210 from edo-zhou/fix/set_height (silvia-odwyer)f19501c— Add adjustments and corrections modules (berkertopuz59)d15af4c— fix: darken not work (edo-zhou)
🔒Security observations
The Photon codebase demonstrates a reasonable security posture with a defined security policy and GitHub Security Advisories support. However, there are areas for improvement: the security update support window is narrow (only 0.3.2), pre-compiled WASM binaries lack integrity verification mechanisms, and automated security scanning is not evident in CI/CD pipelines. No critical vulnerabilities (hardcoded secrets, SQL injection, XSS patterns, or exposed credentials) were identified in the visible structure. The repository is well-maintained with proper workflows and documentation. Recommendations focus on enhancing automated security practices, expanding security guidance for users, and improving supply chain security through binary verification and dependency auditing.
- Low · Limited Version Support in Security Policy —
SECURITY.md. The SECURITY.md file indicates that only version 0.3.2 is currently supported with security updates. This is a narrow support window, and older versions may have unpatched vulnerabilities. Users on other versions lack guaranteed security patching. Fix: Establish a clear versioning and support strategy (e.g., support last 2-3 minor versions). Consider using semantic versioning with long-term support (LTS) branches if applicable. - Low · Pre-compiled WASM Binaries Without Integrity Verification —
docs/*.module.wasm. The repository contains pre-compiled WebAssembly binaries in the /docs directory (.module.wasm files) without visible checksums, signatures, or integrity verification mechanisms. Users cannot verify the authenticity of these binaries. Fix: Generate and publish cryptographic checksums (SHA-256) or signatures for WASM binaries. Consider using tools like subresource integrity (SRI) for web-based distribution. - Low · No Explicit Security Scanning in CI/CD Pipeline —
.github/workflows/ci.yml, .github/workflows/compile_wasm.yaml. While CI/CD workflows are present (.github/workflows/ci.yml), there is no evidence of automated security scanning (SAST, dependency auditing, or SBOM generation) based on the visible configuration. Fix: Integrate security scanning tools such ascargo audit,cargo-deny,trivy, or SAST tools into the CI/CD pipeline. Generate and maintain an SBOM (Software Bill of Materials). - Low · Missing Documentation on Security Best Practices —
SECURITY.md. The SECURITY.md file does not include guidance on secure usage of the library (e.g., input validation, safe image handling, memory limits for WASM execution). Fix: Expand SECURITY.md to include security best practices for library users, such as input validation recommendations, memory/resource limits, and safe usage patterns. - Informational · Bundled Fonts Without License Verification —
crate/fonts/. The codebase includes TTF fonts (Roboto-Black.ttf, Roboto-Regular.ttf) in /crate/fonts/. While an Apache License is noted, there is no evidence of license compliance verification in the build or CI/CD process. Fix: Document font licenses clearly in LICENSE files and verify license compliance (e.g., using REUSE compliance tools or license scanners) as part of CI/CD.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.