Skip to main content
Thank you for your interest in contributing to Frame! This guide covers the development workflow, coding standards, testing requirements, and submission process.

Technical Stack

Frame is built with:
  • Backend: Rust (Tauri v2, Edition 2024)
  • Frontend: Svelte 5 (TypeScript, Runes API)
  • Runtime: Tokio (async I/O)
  • Package Manager: Bun (or Node.js)
  • Core Engine: FFmpeg & FFprobe (sidecars)

Getting Started

Prerequisites

Before contributing, ensure you have:
  1. Rust: Install from rust-lang.org
  2. Bun: Install from bun.sh
  3. Tauri Dependencies: Follow the Tauri setup guide

Local Setup

1

Fork and clone the repository

Fork the repository on GitHub, then clone your fork:
git clone https://github.com/YOUR_USERNAME/frame.git
cd frame
2

Install dependencies

Install all frontend dependencies:
bun install
3

Setup FFmpeg binaries

Download FFmpeg and FFprobe sidecars:
bun run setup:ffmpeg
This fetches platform-specific binaries and places them in src-tauri/binaries/.
4

Setup AI upscaler (optional)

If working on upscaling features:
bun run setup:upscaler
5

Run in development mode

Launch the application with hot reload:
bun tauri dev
This starts:
  • Vite development server (port 5173)
  • Rust backend compilation
  • Application window with HMR

Project Structure

Understanding the codebase organization:

Backend (Rust)

src-tauri/
├── src/
│   ├── lib.rs                # Application entry point
│   ├── main.rs               # Binary entry
│   ├── conversion/           # Media conversion modules
│   │   ├── manager.rs        # Task queue and concurrency control
│   │   ├── worker.rs         # FFmpeg process execution
│   │   ├── probe.rs          # FFprobe metadata extraction
│   │   ├── upscale.rs        # AI upscaling pipeline
│   │   ├── args.rs           # FFmpeg argument building
│   │   ├── codec.rs          # Codec configuration
│   │   ├── filters.rs        # Filter chain construction
│   │   ├── types.rs          # Data structures
│   │   ├── commands.rs       # Tauri IPC commands
│   │   └── tests.rs          # Unit tests
│   ├── dialog.rs             # Native dialog integration
│   └── capabilities.rs       # Capability detection
├── binaries/                 # FFmpeg/FFprobe sidecars (gitignored)
├── resources/                # Bundled resources (models, etc.)
└── Cargo.toml                # Rust dependencies

Frontend (Svelte)

src/
├── routes/
│   ├── +page.svelte          # Main application
│   ├── +layout.svelte        # Root layout
│   └── splash/+page.svelte   # Splash screen
├── lib/
│   ├── components/           # UI components
│   │   ├── file-list/        # File list view
│   │   ├── settings/         # Settings panels
│   │   │   └── tabs/         # Settings tabs (Video, Audio, etc.)
│   │   ├── logs/             # Logs viewer
│   │   └── ui/               # Reusable UI primitives
│   ├── stores/               # State management ($state)
│   ├── services/             # Tauri IPC services
│   ├── features/             # Feature modules
│   ├── i18n/                 # Translations
│   └── types.ts              # TypeScript types
└── package.json              # Frontend dependencies

Development Workflow

Creating a Feature or Fix

1

Create a new branch

Branch from main with a descriptive name:
git checkout -b feature/add-av1-encoder
# or
git checkout -b fix/progress-calculation-overflow
Branch naming conventions:
  • feature/*: New features
  • fix/*: Bug fixes
  • refactor/*: Code refactoring
  • docs/*: Documentation updates
2

Make your changes

Follow the coding standards below. Test frequently with:
bun tauri dev
3

Commit your changes

Write clear, descriptive commit messages:
git commit -m "feat: add AV1 encoder support with SVT-AV1"
git commit -m "fix: prevent progress overflow for long videos"
Commit message format:
  • feat: New features
  • fix: Bug fixes
  • refactor: Code refactoring
  • docs: Documentation
  • test: Tests
  • chore: Build/tooling changes
4

Push to your fork

git push origin feature/add-av1-encoder

Code Review Process

All contributions go through code review:
  1. Maintainers review for code quality, architecture fit, and test coverage
  2. Feedback is provided via PR comments
  3. Address feedback by pushing additional commits
  4. Once approved, maintainers merge the PR

Coding Standards

Rust (Backend)

Use cargo fmt for consistent formatting:
cd src-tauri
cargo fmt
This enforces:
  • 4-space indentation
  • 100-character line width
  • Rust standard style guide

Frontend (TypeScript/Svelte)

Use Prettier for formatting:
bun run format
Configuration in .prettierrc:
  • 2-space indentation
  • Single quotes
  • Tailwind class sorting via prettier-plugin-tailwindcss

FFmpeg Integration

When adding new FFmpeg features:
  1. Validation: Add validation logic in src-tauri/src/conversion/types.rs (ConversionConfig)
  2. Arguments: Update src-tauri/src/conversion/args.rs to build FFmpeg args
  3. UI: Add controls in relevant settings tab (src/lib/components/settings/tabs/)
  4. Documentation: Update inline help text and user-facing docs
Example: Adding a new video encoder
// src-tauri/src/conversion/codec.rs
pub fn add_video_codec_args(args: &mut Vec<String>, config: &ConversionConfig) {
    match config.video_codec.as_str() {
        "libx264" => { /* ... */ },
        "libx265" => { /* ... */ },
        "libsvtav1" => {  // New encoder
            args.push("-c:v".to_string());
            args.push("libsvtav1".to_string());
            // Add encoder-specific flags
        },
        _ => {}
    }
}

Testing & Quality Control

Before submitting a pull request, ensure all checks pass:
1

Run the build

Verify the project builds without errors:
bun tauri build --no-bundle
This compiles both frontend and backend.
2

Run Rust tests

Execute all backend unit tests:
cd src-tauri
cargo test
Add tests for new functionality in src-tauri/src/conversion/tests.rs.
3

Type check frontend

Run Svelte type checking:
bun run check
4

Lint code

Run linters for both frontend and backend:
bun run lint
cd src-tauri && cargo clippy -- -D warnings
5

Format code

Format all code:
bun run format
cd src-tauri && cargo fmt
6

Test i18n integrity

Validate internationalization keys:
bun run i18n:check
This ensures:
  • All locale files have consistent keys
  • No missing translations
  • Placeholder consistency across locales

Manual Testing

Test your changes manually:
  1. Conversion Testing: Test with various media files (different codecs, containers, resolutions)
  2. Edge Cases: Test with corrupted files, very long videos, high resolutions
  3. UI Testing: Verify UI responsiveness and accessibility
  4. Cross-Platform: If possible, test on macOS, Windows, and Linux

Translation Workflow

Frame supports multiple languages. When adding UI text:
1

Add English source text

Edit src/lib/i18n/locales/en-US.json:
{
  "settings.video.encoder": "Video Encoder",
  "settings.video.encoder.description": "Select the video codec for encoding"
}
en-US is the source-of-truth locale.
2

Extract and sync keys

Run the sync script to propagate new keys:
bun run i18n:sync:write
This:
  • Adds new keys to all locale files
  • Marks them with TODO prefix (English fallback)
  • Removes stale keys
3

Auto-translate (optional)

If you have a DeepL API key:
export DEEPL_API_KEY="your-key"
bun run i18n:translate:write
This auto-translates new TODO-marked keys.
4

Validate translations

Check translation integrity:
bun run i18n:check

Translation Scripts

ScriptDescription
i18n:extractExtract i18n keys from source code
i18n:checkValidate locale integrity
i18n:syncPreview sync changes (dry run)
i18n:sync:writeApply sync changes
i18n:translate:writeAuto-translate new keys via DeepL
i18n:translate:rewriteRe-translate all keys (overwrite existing)
i18n:sync:autoSync + auto-translate in one step
Reference: package.json:14-21

Pull Request Process

1

Create a pull request

On GitHub, create a PR from your branch to main.PR Title: Use conventional commit format
feat: add SVT-AV1 encoder support
fix: resolve progress bar overflow on 4K videos
2

Provide a clear description

Include:
  • Summary: What does this PR do?
  • Motivation: Why is this change needed?
  • Changes: List of modified files/modules
  • Testing: How did you test this?
  • Screenshots: For UI changes
  • Related Issues: Link to issue numbers (e.g., “Fixes #123”)
Example:
## Summary
Adds support for the SVT-AV1 encoder (`libsvtav1`) for AV1 encoding.

## Motivation
SVT-AV1 is faster than libaom-av1 and produces comparable quality.

## Changes
- Updated `codec.rs` to add `libsvtav1` case
- Added encoder presets (speed 0-13) in `args.rs`
- Updated VideoTab.svelte to include SVT-AV1 in encoder dropdown

## Testing
- Tested 1080p and 4K encoding with speed presets 6, 8, 10
- Verified correct argument generation in logs
- Confirmed output playback in VLC and mpv

## Related Issues
Fixes #456
3

Wait for review

Maintainers will review your PR. This may take a few days.Address feedback by:
  • Pushing additional commits to your branch
  • Responding to comments
4

Merge

Once approved, maintainers will merge your PR.Your contribution will be included in the next release!

Reporting Issues

If you find a bug or have a feature request:
  1. Search Existing Issues: Check if it’s already reported at github.com/66HEX/frame/issues
  2. Create a New Issue: If not found, open a new issue
  3. Provide Details:
    • Bug Reports: Include OS, Frame version, FFmpeg logs (from “Logs” view), steps to reproduce
    • Feature Requests: Describe the feature, use case, and expected behavior

Issue Templates

**Frame Version**: 0.25.3
**OS**: macOS 14.2 (Apple Silicon)
**FFmpeg Version**: (from Help > About)

**Description**:
Progress bar freezes at 50% when converting HEVC to H.264.

**Steps to Reproduce**:
1. Load HEVC file (1080p, 10-bit)
2. Select H.264 encoder, CRF 23
3. Start conversion
4. Progress stops at 50%, but FFmpeg continues

**Logs**:
(Paste from Logs view)

Code of Conduct

Frame follows the Contributor Covenant Code of Conduct.

Our Pledge

We pledge to make participation in our community a harassment-free experience for everyone, regardless of:
  • Age, body size, disability, ethnicity
  • Gender identity and expression
  • Level of experience, education, socio-economic status
  • Nationality, personal appearance, race, religion
  • Sexual identity and orientation

Our Standards

Positive behaviors:
  • Demonstrating empathy and kindness
  • Being respectful of differing opinions and experiences
  • Giving and gracefully accepting constructive feedback
  • Accepting responsibility and apologizing for mistakes
  • Focusing on what is best for the community
Unacceptable behaviors:
  • Sexualized language or imagery, unwelcome advances
  • Trolling, insulting/derogatory comments, personal attacks
  • Public or private harassment
  • Publishing others’ private information without permission

Enforcement

Instances of abusive or harassing behavior may be reported to [email protected]. All complaints will be reviewed and investigated promptly and fairly. Reference: CODE_OF_CONDUCT.md

Financial Support

If you want to support Frame’s development (especially code-signing for macOS and Windows builds), consider sponsoring: Funding Goals:
  • Apple Developer Program: $99/year for macOS signing and notarization
  • Microsoft Code Signing Certificate: $300-700/year for Windows signing
Sponsorship contributions are used first for release-signing costs to reduce security warnings for users.

License

By contributing to Frame, you agree that your contributions will be licensed under the GPL-3.0-or-later license. See LICENSE for details.

Next Steps

Building from Source

Set up your development environment

Architecture

Understand Frame’s technical architecture

Build docs developers (and LLMs) love