## File: README.md

<a href="https://graphite.art/">





</a>

# Your procedural toolbox for 2D content creation

**Graphite is a free, open source vector and raster graphics engine, [available now](https://editor.graphite.art) in alpha. Get creative with a fully nondestructive editing workflow that combines layer-based compositing with node-based generative design.**

Having begun life as a vector editor, Graphite continues evolving into a generalized, all-in-one graphics toolbox that's built more like a game engine than a conventional creative app. The editor's tools wrap its node graph core, providing user-friendly workflows for vector, raster, and beyond. Photo editing, motion graphics, digital painting, desktop publishing, and VFX compositing are additional competencies on the planned [roadmap](https://graphite.art/features/#roadmap) making Graphite into a highly versatile content creation tool.

Learn more from the [website](https://graphite.art/), subscribe to the [newsletter](https://graphite.art/#newsletter), consider [volunteering](https://graphite.art/volunteer/) or [donating](https://graphite.art/donate/), and remember to give this repository a ⭐!


<a href="https://discord.graphite.art/">





</a>
&nbsp;&nbsp;&nbsp;&nbsp;
<a href="https://www.reddit.com/r/graphite/">





</a>
&nbsp;&nbsp;&nbsp;&nbsp;
<a href="https://bsky.app/profile/graphiteeditor.bsky.social">





</a>
&nbsp;&nbsp;&nbsp;&nbsp;
<a href="https://twitter.com/graphiteeditor">





</a>
&nbsp;&nbsp;&nbsp;&nbsp;
<a href="https://www.youtube.com/@GraphiteEditor">





</a>


https://github.com/user-attachments/assets/f4604aea-e8f1-45ce-9218-46ddc666f11d

## Support our mission ❤️

Graphite is 100% community built and funded. Please become a part of keeping the project alive and thriving with a [donation](https://graphite.art/donate/) if you share a belief in our **mission**:

> Graphite strives to unshackle the creativity of every budding artist and seasoned professional by building the best comprehensive art and design tool that's accessible to all.
> 
> Mission success will come when Graphite is an industry standard. A cohesive product vision and focus on innovation over imitation is the strategy that will make that possible.

## Screenshots







## Contributing/building the code

Are you a graphics programmer or Rust developer? Graphite aims to be one of the most approachable projects for putting your engineering skills to use in the world of open source. See [instructions here](https://graphite.art/volunteer/guide/) for setting up the project and getting started.

*By submitting code for inclusion in the project, you are agreeing to license your changes under the Apache 2.0 license, and that you have the authority to do so. Some directories may have other licenses, like dual-licensed MIT/Apache 2.0, and code submissions to those directories mean you agree to the applicable license(s).*

---

## File: frontend/src/components/README.md

# Overview of `/frontend/src/components/`

Each component represents a (usually reusable) part of the Graphite editor GUI.

## Floating Menus: `floating-menus/`

The temporary UI areas with dark backgrounds which hover over the top of the editor window content. Examples include menu lists, popovers, and dialogs.

## Layout: `layout/`

Useful containers that control the flow of content held within.

## Panels: `panels/`

The dockable tabbed regions like the Document, Properties, Layers, Data, and Welcome panels.

## Views: `views/`

Content views rendered within panels, such as the node graph.

## Widgets: `widgets/`

The interactive input items used to display information and provide user control.

## Window: `window/`

The building blocks for the Title Bar, Workspace, and Status Bar within an editor application window.

# Svelte tips and tricks

This section contains a growing list of quick reference information for helpful Svelte solutions and best practices. Feel free to add to this to help contributors learn things, or yourself remember tricks you'll likely forget in a few months.

## Bi-directional props

The component declares this:

```ts
// The dispatcher that sends the changed value as a custom event to the parent
const dispatch = createEventDispatcher<{ theBidirectionalProperty: number }>();

// The prop
export let theBidirectionalProperty: number;

// Called only when `theBidirectionalProperty` is changed from outside this component via its props
$: console.log(theBidirectionalProperty);

// Example of a method that would update the value
function doSomething() {
	dispatch("theBidirectionalProperty", SOME_NEW_VALUE);
},
```

Users of the component do this for `theCorrespondingDataEntry` to be a two-way binding:

```ts
let theCorrespondingDataEntry = 42;
```

```svelte
<DropdownInput
	theBidirectionalProperty={theCorrespondingDataEntry}
	on:theBidirectionalProperty={({ detail }) => { theCorrespondingDataEntry = detail; }}
/>
```

---

## File: frontend/src/README.md

# Overview of `/frontend/src/`

## Svelte components: `components/`

Svelte components that build the Graphite editor GUI from layouts, panels, widgets, and menus. These each contain a TypeScript section, a Svelte-templated HTML template section, and an SCSS stylesheet section. The aim is to avoid implementing much editor business logic here, just enough to make things interactive and communicate to the backend where the real business logic should occur.

## Managers: `managers/`

TypeScript files, constructed by the editor frontend, which manage the input/output of browser APIs and link this functionality with the editor backend. These files subscribe to frontend messages to execute JS APIs, and in response to these APIs or user interactions, they may call functions in the backend (defined in `/frontend/wrapper/editor_wrapper.rs`).

Each manager module stores its dependencies (like `subscriptionsRouter` and `editorWrapper`) in module-level variables and exports a `create*()` and `destroy*()` function pair. `Editor.svelte` calls each `create*()` constructor in its `onMount` and calls each `destroy*()` in its `onDestroy`. Managers replace themselves during HMR updates if they are modified live during development.

## Stores: `stores/`

TypeScript files, constructed by the editor frontend, which provide reactive state to Svelte components. Each module persists a Svelte writable store at module level (surviving HMR via `import.meta.hot.data`) and exports a `create*()` function that sets up frontend message subscriptions and returns `{ subscribe }` (the shape required by Svelte's custom store contract). A corresponding `destroy*()` function is also exported. Some stores also export standalone action functions (like `createCrashDialog()` or `toggleFullscreen()`) as module-level exports.

In `Editor.svelte`, each store is created synchronously during component initialization (not in `onMount`, since child components need `getContext` access during their own initialization) and passed to Svelte's `setContext()`. Components access stores via calls like `getContext<DialogStore>("dialog")`. Unlike managers, stores do not replace themselves during HMR; instead, `Editor.svelte` is remounted to replace them entirely.

## *Managers vs. stores*

*Both managers and stores subscribe to frontend messages and may interact with browser APIs. The difference is that stores expose reactive state to components via `setContext()`/`getContext()`, while managers are self-contained systems that operate for the lifetime of the application and aren't accessed by Svelte components.*

## Utility functions: `utility-functions/`

TypeScript files which define and `export` individual helper functions for use elsewhere in the codebase. These files should not persist state outside each function.

## Subscriptions router: `subscriptions-router.ts`

Associates messages from the backend with subscribers in the frontend, and routes messages to subscriber callbacks. This module provides a `subscribeFrontendMessage(messageType, callback)` function which JS code throughout the frontend can call to be registered as the exclusive handler for a chosen message type. The router's other function, `handleFrontendMessage(messageType, messageData)`, is called via the callback passed to `EditorWrapper.create()` in `App.svelte` when the backend sends a `FrontendMessage`. When this occurs, the subscriptions router delivers the message to the subscriber by executing its registered `callback` function.

## Svelte app entry point: `App.svelte`

The entry point for the Svelte application. Initializes and creates the `EditorWrapper` backend instance and the subscriptions router and renders `Editor.svelte` once both are ready. The `EditorWrapper` is the wasm-bindgen interface to the Rust editor backend (defined in `/frontend/wrapper/editor_wrapper.rs`), providing access to callable backend functions. Both the editor and subscriptions router are passed as props to `Editor.svelte` and set as Svelte contexts for use throughout the component tree.

## Editor base instance: `Editor.svelte`

This is where we define global CSS style rules, construct all stores and managers, set store contexts for component access, and call each module's `destroy*()` function on unmount (on HMR during development).

## Global type augmentations: `global.d.ts`

Extends built-in browser type definitions using TypeScript's interface merging. This includes Graphite's custom properties on the `window` object, custom events like `pointerlockmove`, and experimental browser APIs not yet in TypeScript's standard library. New custom events or non-standard browser APIs used by the frontend should be declared here.

## JS bundle entry point: `main.ts`

The entry point for the entire project's code bundle. Mounts the Svelte application with `export default mount(App, { target: document.body })`.

---

## File: frontend/README.md

# Overview of `/frontend/`

The Graphite frontend is a web app that provides the presentation for the editor. It displays the GUI based on state from the backend and provides users with interactive widgets that send updates to the backend, which is the source of truth for state information. The frontend is built out of reactive components using the [Svelte](https://svelte.dev/) framework. The backend is written in Rust and compiled to WebAssembly (Wasm) to be run in the browser alongside the JS code.

## Bundled assets: `assets/`

Images that are used in components and embedded into the application bundle by the build system.

## Svelte/TypeScript source: `src/`

Source code for the web app in the form of Svelte components and [TypeScript](https://www.typescriptlang.org/) files.

## Editor wrapper: `wrapper/`

Wraps the editor backend codebase (`/editor`) and provides a JS-centric API for the web app to use as an entry point, unburdened by Rust's complex data types that are incompatible with JS data types. Bindings (JS functions that call into the Wasm module) are provided by `wasm-bindgen`. As part of `cargo run`, our build tool compiles this crate to Wasm, runs the `wasm-bindgen` CLI to generate the JS/TS bindings in `wrapper/pkg/`, and (for release builds) optimizes the binary with Binaryen's `wasm-opt`.

## ESLint configuration: `eslint.config.js`

When you use `npm run check`, [ESLint](https://eslint.org/) checks the code in the frontend project for code quality. (The command also reports TS and Svelte errors.) The tool enforces style rules on the JS, TS, and Svelte (including its HTML and SCSS) files in our frontend codebase. As it is set up in this config file, ESLint will complain about bad practices and often help reformat code automatically when the file is saved in VS Code, or manually when `npm run fix` is executed. (If you don't use VS Code, remember to run this command before committing!) This config file for ESLint sets our style preferences and configures our usage of extensions/plugins for Svelte support and [Prettier](https://prettier.io/)'s role as a code formatter.

## Svelte configuration: `svelte.config.js`

Configures the Svelte compiler, including the preprocessor setup for SCSS and TypeScript support, and compiler warning filters.

## TypeScript configuration: `tsconfig.json`

Basic configuration options for the TypeScript build tool to do its job in our repository.

## Vite configuration: `vite.config.ts`

We use the [Vite](https://vitejs.dev/) bundler/build system. This file is where we configure Vite to set up plugins (like the third-party license checker/generator). Part of the license checker plugin setup includes some functions to format web package licenses, as well as Rust package licenses provided by [cargo-about](https://github.com/EmbarkStudios/cargo-about), into a text file that's distributed with the application to provide license notices for third-party code.

## npm ecosystem packages: `package.json`

While we don't use Node.js as a JS-based server, we do rely on its ecosystem of packages for our build system toolchain. Our project's philosophy on third-party packages is to keep our dependency tree as light as possible, so adding anything new to our `package.json` should have overwhelming justification. Most of the packages are just development tooling (TypeScript, Vite, ESLint, Prettier, Sass, etc.) that run in your terminal during the build process.

## npm package installed versions: `package-lock.json`

Specifies the exact versions of packages installed in the npm dependency tree. While `package.json` specifies which packages to install and their minimum/maximum acceptable version numbers, `package-lock.json` represents the exact versions of each dependency and sub-dependency. Running `npm ci` will grab these exact versions to ensure you are using the same packages as everyone else working on Graphite. `npm update` will modify `package-lock.json` to specify newer versions of any updated (sub-)dependencies and download those, as long as they don't exceed the maximum version allowed in `package.json`. To check for newer versions that exceed the max version, run `npm outdated` to see a list. Unless you know why you are doing it, try to avoid committing updates to `package-lock.json` by mistake if your code changes don't pertain to package updates. And never manually modify the file.

---

## File: libraries/rawkit/rawkit-proc-macros/README.md

# Rawkit-proc-macros

Procedural macros for Rawkit.

This library is intended to be used by Rawkit. You should not be depending on this crate directly.

### Tag

A derive macro that helps to specify which metadata needs to be extracted from IFD.

### build_camera_data

A procedural macro that reads the data of all cameras from the toml files and returns the bundled data. Helps to include camera data as part of binary.

---

## File: libraries/rawkit/README.md

[crates.io](https://crates.io/crates/rawkit) • [docs.rs](https://docs.rs/rawkit) • [repo](https://github.com/GraphiteEditor/Graphite/tree/master/libraries/rawkit)

# Rawkit 🚀

A library to extract images from camera raw files.

It currently only works with the `.arw` files from Sony's cameras. In the future, the library will add support for all other major camera manufacturers.

Rawkit is built for the needs of [Graphite](https://graphite.art), an open source 2D graphics editor. We hope it may be useful to others, but presently Graphite is its primary user. Pull requests are welcomed for new cameras, features, code cleanup, ergonomic enhancements, performance improvements, and documentation clarifications.

### Using Rawkit

```rust
use rawkit::RawImage;
use rawkit::tiff::values::Transform;

// Open a file for reading
let file = BufReader::new(File::open("example.arw")?);

// Decode the file to extract the raw pixels and its associated metadata
let mut raw_image = RawImage::decode(file);

// All the raw pixel data and metadata is stored within `raw_image`
println!("Initial Bayer pixel values: {:?}", raw_image.data[:10]);
println!("Image size: {} x {}", raw_image.width, raw_image.height);
println!("CFA Pattern: {:?}", raw_image.cfa_pattern);
println!("Camera Model: {:?}", raw_image.camera_model);
println!("White balance: {:?}", raw_image.white_balance);

// The metadata could also be edited if the extracted metadata needs to be customized
raw_image.white_balance = Some([2609, 1024, 1024, 1220]); // For RGGB camera
raw_image.transform = Transform::Rotate90;

// Process the raw image into an RGB image
let image = raw_image.process_8bit();

// The final image data will be stored within `image`
println!("Initial RGB pixel values: {:?}", image.data[:10]);
println!("Image size: {} x {}", image.width, image.height);
```

---

## File: libraries/dyn-any/README.md

# DynAny Trait


A `Any`-like trait and derive macros for non `'static` lifetimes.