mui-image-editor
v0.3.4
Published
A React image editor component built with Material-UI
Maintainers
Readme
MUI Image Editor
A powerful, feature-rich React image editor component built with Material-UI. Edit images directly in your React applications with support for cropping, rotation, flipping, drawing, custom filters, and more.

Table of Contents
- Features
- Installation
- Quick Start
- Component Props
- Imperative API (EditorHandle)
- Editing Tools
- Custom Filters
- Custom Tools
- Internationalization (i18n)
- Theming & Design Tokens
- State Management
- Keyboard Shortcuts
- Viewport & Navigation
- Operation Types
- Exports
- Browser Support
- Development
Features
- 🎨 Comprehensive Editing Tools — Crop, rotate, flip, draw, and apply filters.
- ✏️ Freehand Drawing — Brush with adjustable color, size, opacity, and an eraser tool.
- 🖼️ Advanced Image Processing — High-quality canvas-based rendering with undo/redo, before/after comparison, and zoom/pan controls.
- 🔌 Extensible Filter System — Plug in your own filters with rich UI controls (sliders, checkboxes, selects, color pickers).
- 🌍 Internationalization — Built-in English and Polish translations. Supply your own locale strings or translation function.
- 🎯 Imperative API — Full programmatic control via React refs: save, reset, undo, redo, zoom, get/set state.
- 📐 Grid Overlays — Rule of thirds, golden ratio, and pixel grid overlays.
- ⚡ Performance — Efficient rendering engine with configurable preview scale, history management, and optional WebGL support.
- 🎨 Fully Themeable — Customize colors, spacing, and typography via Material-UI theming and design tokens.
Installation
npm install mui-image-editorPeer Dependencies
This package requires the following peer dependencies to be installed in your project:
npm install react react-dom @mui/material @mui/icons-material @emotion/react @emotion/styled| Peer Dependency | Version |
|------------------------|------------|
| react | ^18.3.1 |
| react-dom | ^18.3.1 |
| @mui/material | ^7.1.2 |
| @mui/icons-material | ^7.1.2 |
| @emotion/react | ^11.0.0 |
| @emotion/styled | ^11.0.0 |
Quick Start
import React, { useRef } from 'react';
import { ImageEditor, EditorHandle } from 'mui-image-editor';
function App() {
const editorRef = useRef<EditorHandle>(null);
return (
<ImageEditor
src="https://example.com/photo.jpg"
onSave={(result) => {
// result: { blob, dataUrl?, format, width, height, operations, exif? }
const url = URL.createObjectURL(result.blob);
const a = document.createElement('a');
a.href = url;
a.download = `edited.${result.format}`;
a.click();
URL.revokeObjectURL(url);
}}
ref={editorRef}
/>
);
}Note: The
ImageEditorcomponent fills its parent container. Ensure the parent element has explicitwidthandheight(or usesflexlayout) so the editor renders correctly.
Component Props
Required Props
| Prop | Type | Description |
|----------|-----------------------------------------------|-----------------------------------------------------|
| src | string | Image source URL or data URI to edit. |
| onSave | (result: SaveResult) => void | Callback invoked when the user triggers a save. |
SaveResult Shape
{
blob: Blob; // The edited image as a Blob
dataUrl?: string; // Data URL (only if output.returnDataUrl is true)
format: "png" | "jpeg" | "webp"; // Output format
width: number; // Final image width in pixels
height: number; // Final image height in pixels
operations: OperationManifest; // Array of all operations applied
exif?: Record<string, any>; // EXIF data (if preserveExif is true)
}Optional Props
| Prop | Type | Default | Description |
|------------------|-------------------------------------------------------------------------------|--------------------|--------------------------------------------------------------------------------------------------|
| crossOrigin | "anonymous" \| "use-credentials" \| null | "anonymous" | CORS setting for image loading. |
| imageLoader | (src: string) => Promise<Blob \| ArrayBuffer \| File> | — | Custom image loader function (e.g., for authenticated endpoints). Bypasses default URL loading. |
| initialState | EditorState | — | Initial editor state to restore (operations, viewport). See State Management.|
| onChange | (preview: HTMLCanvasElement \| ImageBitmap, operations: OperationManifest) => void | — | Callback on every edit operation. Useful for auto-save or live previews. |
| onError | (err: Error) => void | — | Error handler for image loading failures. |
| output | OutputOptions | — | Configure output format, quality, and sizing. See Output Options. |
| ui | UIOptions | — | UI customization. See UI Options. |
| filters | FilterDefinition[] | [traceLinesFilter]| Array of filter definitions. See Custom Filters. |
| tools | ToolDefinition[] | — | Custom tool definitions. See Custom Tools. |
| availableTools | ToolId[] | All tools | Restrict which built-in tools are shown. Possible values: "crop", "rotate", "flip", "filters", "draw". |
| engine | EngineOptions | — | Engine performance options. See Engine Options. |
| locale | SupportedLocale | "en" | Shorthand for built-in translations ("en" or "pl"). See Internationalization. |
| i18n | I18nOptions | — | Advanced internationalization options. See I18n Options. |
Output Options
Control what the onSave callback receives.
output?: {
format?: "png" | "jpeg" | "webp"; // Default: "png"
quality?: number; // Default: 0.92 (for jpeg/webp, ignored for png)
preserveExif?: boolean; // Default: false — preserve original EXIF data
background?: string | null; // Background color for transparent areas (e.g., "#ffffff")
colorProfile?: "sRGB" | "display-p3" | "auto"; // Color profile handling
returnDataUrl?: boolean; // Default: false — include dataUrl in SaveResult
maxSize?: {
width?: number; // Maximum output width
height?: number; // Maximum output height
fit?: "contain" | "cover" | "downscaleOnly"; // How to fit within maxSize
};
}Example — Save as JPEG, limit to 1080p:
<ImageEditor
src="/photo.jpg"
output={{
format: 'jpeg',
quality: 0.85,
returnDataUrl: true,
maxSize: { width: 1920, height: 1080, fit: 'contain' }
}}
onSave={(result) => {
console.log(`Saved ${result.width}×${result.height} ${result.format}`);
}}
/>UI Options
Customize the editor's appearance and behavior.
ui?: {
themeMode?: "light" | "dark" | "system"; // Default: inherits from MUI ThemeProvider
themeOverrides?: object; // MUI theme overrides (createTheme options)
tokens?: Partial<DesignTokens>; // Design token overrides (see Theming section)
toolbarPosition?: "top" | "left" | "right"; // Where the toolbar is rendered
showGrid?: boolean; // Show grid overlays on the canvas
gridType?: "ruleOfThirds" | "goldenRatio" | "pixel" | "none"; // Default: "ruleOfThirds"
snapping?: boolean; // Enable snap-to-grid behavior
keyboardShortcuts?: boolean; // Default: true
mobileLayout?: "compact" | "auto"; // Mobile layout mode
}Engine Options
Fine-tune rendering performance.
engine?: {
previewScale?: number; // Preview resolution scale (e.g., 0.5 for half-res previews)
useWebGL?: boolean; // Use WebGL for filter rendering (if available)
workerCount?: number; // Number of web workers for parallel processing
keyframeEvery?: number; // How often to snapshot for instant undo (lower = more memory, faster undo)
maxHistoryBytes?: number; // Maximum memory for undo history (bytes)
downscaleLargeImages?: {
maxMP?: number; // Max megapixels before auto-downscaling
method?: "pica" | "canvas"; // Downscale method ("pica" is higher quality)
};
}I18n Options
For most use cases, set the top-level locale prop instead:
<ImageEditor src="/photo.jpg" locale="pl" onSave={handleSave} />For advanced customization (custom translation function, partial string overrides, RTL), use the i18n prop:
i18n?: {
t?: (key: string, params?: Record<string, any>) => string; // Custom translation function
strings?: Partial<Record<EditorStringKey, string>>; // Override specific strings
locale?: string; // Locale code (overrides the top-level locale prop)
rtl?: boolean; // Enable right-to-left layout
}Resolution priority: i18n.t() → i18n.strings → built-in translations for i18n.locale (or top-level locale, or "en").
See the Internationalization section for detailed usage.
Imperative API (EditorHandle)
Access the editor programmatically via a React ref:
import React, { useRef } from 'react';
import { ImageEditor, EditorHandle } from 'mui-image-editor';
function App() {
const editorRef = useRef<EditorHandle>(null);
return (
<>
<button onClick={() => editorRef.current?.save()}>Save</button>
<button onClick={() => editorRef.current?.undo()}>Undo</button>
<button onClick={() => editorRef.current?.redo()}>Redo</button>
<button onClick={() => editorRef.current?.reset()}>Reset</button>
<button onClick={() => editorRef.current?.zoomToFit()}>Fit</button>
<ImageEditor src="/photo.jpg" onSave={console.log} ref={editorRef} />
</>
);
}Available Methods
| Method | Return Type | Description |
|----------------------------------------------|--------------------|--------------------------------------------------------------------------|
| save() | Promise<void> | Render the full-resolution image and invoke the onSave callback. |
| reset() | void | Reset the image to its original, unedited state. |
| undo() | void | Undo the last operation. |
| redo() | void | Redo the last undone operation. |
| zoomToFit() | void | Fit the entire image in the viewport. |
| zoom(scale: number) | void | Set the zoom level (clamped to 0.05 – 8). |
| getState() | EditorState | Get the current editor state (operations, viewport, image metadata). |
| setState(state: EditorState) | void | Restore a previously saved editor state. |
Editing Tools
The editor provides five built-in tools, each accessible from the tool panel on the right side of the editor.
Crop
Select a region of the image to keep. The crop tool supports:
- Free-form cropping — drag to create any rectangle.
- Aspect ratio presets — 1:1, 4:3, 3:2, 16:9, 9:16.
- Lock ratio — toggle to constrain the crop rectangle to the selected aspect ratio.
- Resize handles — drag corner and edge handles to adjust.
- Move — drag the crop rectangle to reposition.
- Apply / Cancel — commit or discard the crop.
Rotate
Rotate the image with fine-grained control:
- Step rotation — quick -90° and +90° buttons for quarter turns.
- Fine angle slider — adjust from -45° to +45° in 0.1° increments with real-time preview.
- Angle text input — type an exact angle value.
- Expand canvas — toggle whether the canvas grows to fit the rotated image (on) or clips it (off).
- Background color — choose the fill color for areas revealed by rotation.
- Apply / Cancel — commit the rotation or revert to the pre-rotation state.
Flip
Mirror the image instantly:
- Flip Horizontal — mirror along the vertical axis (left ↔ right).
- Flip Vertical — mirror along the horizontal axis (top ↔ bottom).
Flips are applied immediately (no apply/cancel step needed).
Draw
Freehand drawing and annotation directly on the image:
- Brush color — pick any color via the color picker.
- Brush size preview — visual indicator of the current brush size.
- Line width — adjust from 1px to 50px.
- Opacity — control brush transparency from 5% to 100%.
- Eraser mode — toggle to erase strokes.
- Undo / Redo — undo and redo individual strokes (separate from the main undo/redo history).
- Clear all — remove all unapplied strokes.
- Apply / Cancel — commit drawn strokes to the image or discard them.
Filters
Apply image filters with live preview:
- Select a filter from the list of registered filters.
- Adjust filter parameters using the auto-generated UI (sliders, selects, checkboxes, color pickers).
- Preview — see the filter effect in real time.
- Apply — commit the filter to the image.
- Cancel — discard the filter.
The editor ships with the Trace Lines edge-detection filter by default. You can provide your own filters — see Custom Filters.
Custom Filters
Filter Definition
Create custom filters by implementing the FilterDefinition interface:
import { FilterDefinition, FilterContext } from 'mui-image-editor';
const myFilter: FilterDefinition = {
id: 'grayscale', // Unique identifier
name: 'Grayscale', // Display name in the UI
version: '1.0.0', // Optional version string (for state serialization)
// UI controls (optional) — auto-generated in the filter panel
ui: [
{ kind: 'slider', key: 'intensity', label: 'Intensity', min: 0, max: 100, step: 1, default: 100 }
],
// Full-quality apply (required)
apply: async (ctx: FilterContext, params: Record<string, any>): Promise<ImageBitmap | ImageData> => {
const bitmap = await ctx.getImageBitmap();
const canvas = ctx.utils.createCanvas(bitmap.width, bitmap.height);
const c = canvas.getContext('2d')!;
c.drawImage(bitmap, 0, 0);
const imgData = c.getImageData(0, 0, canvas.width, canvas.height);
const intensity = (params.intensity ?? 100) / 100;
const { data } = imgData;
for (let i = 0; i < data.length; i += 4) {
const avg = 0.299 * data[i] + 0.587 * data[i+1] + 0.114 * data[i+2];
data[i] = data[i] + (avg - data[i]) * intensity;
data[i+1] = data[i+1] + (avg - data[i+1]) * intensity;
data[i+2] = data[i+2] + (avg - data[i+2]) * intensity;
}
return imgData;
},
// Preview apply (optional) — used for real-time preview, can be lower quality
preview: async (ctx, params) => {
const bitmap = await ctx.getImageBitmap({ preview: true });
// ... same logic on a smaller bitmap for speed
return bitmap;
},
// WebGL apply (optional) — for GPU-accelerated rendering
glApply: (gl, texture, params) => {
// WebGL shader-based implementation
return texture;
}
};Then pass your filters to the editor:
<ImageEditor
src="/photo.jpg"
filters={[myFilter, traceLinesFilter]}
onSave={handleSave}
/>FilterContext API
The FilterContext object is passed to your filter's apply and preview functions:
| Property | Type | Description |
|------------------------|---------------------------------------------------------------|-----------------------------------------------------------------|
| getImageBitmap(opts?) | (opts?: { preview?: boolean }) => Promise<ImageBitmap> | Get the current image. Pass { preview: true } for lower-res. |
| canvas2d | HTMLCanvasElement | Shared canvas for temporary 2D operations. |
| webgl | WebGLRenderingContext \| WebGL2RenderingContext \| undefined | WebGL context (if engine.useWebGL is enabled). |
| abortSignal | AbortSignal \| undefined | Signal that fires if the user cancels the filter. |
| utils.imageData(bitmap) | (bitmap: ImageBitmap) => ImageData | Convert an ImageBitmap to ImageData. |
| utils.createCanvas(w, h) | (w: number, h: number) => HTMLCanvasElement | Create a temporary canvas with the given dimensions. |
Filter UI Parameters
Define auto-generated UI controls for your filter via the ui array:
| Kind | Properties | Description |
|--------------|-----------------------------------------------------------------------------|----------------------------------------------|
| slider | key, label, min, max, step?, default, unit? | Numeric slider with optional unit label. |
| checkbox | key, label, default? | Boolean toggle. |
| select | key, label, options: { label, value }[], default? | Dropdown selection. |
| color | key, label, default? | Color picker. |
Built-in Filter: Trace Lines
The traceLinesFilter is a Sobel edge-detection filter that ships with the component.
import { traceLinesFilter } from 'mui-image-editor';Parameters:
| Parameter | Type | Default | Description |
|-------------|---------|---------|------------------------------------------|
| threshold | Slider | 0.3 | Edge detection sensitivity (0–1). |
| mode | Select | "thin"| Line style: "thin" or "bold" (dilated). |
Custom Tools
Extend the editor with custom tool panels:
import { ToolDefinition, EngineApi } from 'mui-image-editor';
const myTool: ToolDefinition = {
id: 'watermark',
label: 'Watermark',
icon: MyWatermarkIcon, // Optional React component
Render: ({ engine, editorRef }) => {
// Your custom tool UI — engine gives you full access to the editor engine
return <div>My custom tool panel</div>;
},
shortcuts: [ // Optional keyboard shortcuts
{ combo: 'w', action: 'toggleWatermark' }
]
};<ImageEditor
src="/photo.jpg"
tools={[myTool]}
onSave={handleSave}
/>Internationalization (i18n)
Built-in Locales
The editor ships with two built-in locales:
en— English (default)pl— Polish
Use the locale prop — no custom translation function or strings object needed:
<ImageEditor src="/photo.jpg" locale="pl" onSave={handleSave} />The locale prop accepts a SupportedLocale value ("en" | "pl") and provides autocomplete in TypeScript.
Note: If you also pass
i18n={{ locale: '...' }}, thei18n.localevalue takes precedence over the top-levellocaleprop.
Providing Custom Translations
You have three ways to customize the editor's text, listed in order of priority:
1. Custom Translation Function
A function that receives the string key and optional parameters. If it returns a value different from the key, that value is used.
<ImageEditor
src="/photo.jpg"
i18n={{
t: (key, params) => {
// Look up key in your i18n library (e.g., i18next, react-intl)
return myI18n.t(key, params);
}
}}
onSave={handleSave}
/>2. Custom Strings Object
Override individual string keys:
<ImageEditor
src="/photo.jpg"
i18n={{
strings: {
'editor.toolbar.save': 'Export Image',
'editor.tools.crop': 'Trim',
'editor.draw.title': 'Annotate'
}
}}
onSave={handleSave}
/>Strings support placeholder interpolation with {paramName} syntax:
i18n={{
strings: {
'editor.filters.applyFilter': 'Apply the {name} filter'
}
}}3. Built-in Translations (Fallback)
If neither the custom function nor custom strings provide a value, the built-in translation for the selected locale is used.
Translation Key Reference
Toolbar Actions:
| Key | Default (English) |
|-----|-------------------|
| editor.toolbar.save | Save |
| editor.toolbar.undo | Undo |
| editor.toolbar.redo | Redo |
| editor.toolbar.reset | Reset |
| editor.toolbar.beforeAfter | Before/After |
| editor.toolbar.zoomIn | Zoom In |
| editor.toolbar.zoomOut | Zoom Out |
| editor.toolbar.zoomToFit | Zoom to Fit |
| editor.toolbar.panUp | Pan Up |
| editor.toolbar.panDown | Pan Down |
| editor.toolbar.panLeft | Pan Left |
| editor.toolbar.panRight | Pan Right |
| editor.toolbar.more | More |
Tool Names:
| Key | Default (English) |
|-----|-------------------|
| editor.tools.crop | Crop |
| editor.tools.rotate | Rotate |
| editor.tools.flip | Flip |
| editor.tools.filters | Filters |
| editor.tools.draw | Draw |
Crop Tool:
| Key | Default (English) |
|-----|-------------------|
| editor.crop.aspectRatio | Aspect Ratio |
| editor.crop.free | Free |
| editor.crop.lockRatio | Lock ratio |
| editor.crop.instructions | Drag to create a crop. Use handles to resize. Move with drag. Ratios apply when locked. |
Rotate Tool:
| Key | Default (English) |
|-----|-------------------|
| editor.rotate.title | Rotate |
| editor.rotate.fineAngle | Fine Angle |
| editor.rotate.angle | Angle |
| editor.rotate.expandCanvas | Expand canvas |
| editor.rotate.background | Background |
Flip Tool:
| Key | Default (English) |
|-----|-------------------|
| editor.flip.title | Flip |
| editor.flip.horizontal | Flip Horizontal |
| editor.flip.vertical | Flip Vertical |
Filters:
| Key | Default (English) |
|-----|-------------------|
| editor.filters.title | Filters |
| editor.filters.apply | Apply |
| editor.filters.preview | Preview |
| editor.filters.cancel | Cancel |
| editor.filters.noFilters | No filters registered. |
| editor.filters.applyFilter | Apply {name} |
Draw Tool:
| Key | Default (English) |
|-----|-------------------|
| editor.draw.title | Draw |
| editor.draw.color | Brush Color |
| editor.draw.lineWidth | Line Width |
| editor.draw.opacity | Opacity |
| editor.draw.eraser | Eraser |
| editor.draw.clearAll | Clear All |
Using the Built-in Translations Object
You can also import the built-in translations to use as a base for your own:
import { translations } from 'mui-image-editor';
console.log(translations.en); // { "editor.toolbar.save": "Save", ... }
console.log(translations.pl); // { "editor.toolbar.save": "Zapisz", ... }Right-to-Left (RTL) Support
Enable RTL layout for Arabic, Hebrew, and other RTL languages:
<ImageEditor
src="/photo.jpg"
i18n={{ locale: 'ar', rtl: true, strings: { /* ... */ } }}
onSave={handleSave}
/>Theming & Design Tokens
The editor integrates with Material-UI's theming system and exposes its own design tokens for fine-grained control.
Using MUI ThemeProvider
Wrap the editor in a ThemeProvider to inherit your app's theme:
import { ThemeProvider, createTheme } from '@mui/material';
const darkTheme = createTheme({ palette: { mode: 'dark' } });
<ThemeProvider theme={darkTheme}>
<ImageEditor src="/photo.jpg" onSave={handleSave} />
</ThemeProvider>Custom Design Tokens
Override the editor's internal design tokens via the ui.tokens prop:
<ImageEditor
src="/photo.jpg"
ui={{
tokens: {
radius: 16, // Border radius (default: 10)
spacing: 12, // Base spacing unit (default: 8)
toolbarHeight: 64, // Toolbar height in px (default: 56)
colors: {
bg: '#1a1a2e', // Main background
panelBg: '#16213e', // Side panel background
surface: '#0f3460', // Surface elements
primary: '#e94560', // Primary accent color
text: '#f1f1f1', // Text color
outline: 'rgba(255,255,255,0.15)', // Borders and outlines
selection: '#53a8d8' // Selection highlight color
}
}
}}
onSave={handleSave}
/>Default Token Values
| Token | Default |
|----------------------|-------------------------------|
| radius | 10 |
| spacing | 8 |
| toolbarHeight | 56 |
| colors.bg | #0b0b0b |
| colors.panelBg | #1b1b1b |
| colors.surface | #121212 |
| colors.primary | #1976d2 |
| colors.text | #e0e0e0 |
| colors.outline | rgba(255,255,255,0.12) |
| colors.selection | #90caf9 |
State Management
Save and restore the editor's state to enable features like session persistence, collaborative editing, or preset management.
Saving State
const editorRef = useRef<EditorHandle>(null);
const saveToLocalStorage = () => {
const state = editorRef.current?.getState();
if (state) {
localStorage.setItem('editorState', JSON.stringify(state));
}
};Restoring State
const [initialState, setInitialState] = useState<EditorState | undefined>();
useEffect(() => {
const saved = localStorage.getItem('editorState');
if (saved) setInitialState(JSON.parse(saved));
}, []);
return (
<ImageEditor
src="/photo.jpg"
initialState={initialState}
onSave={handleSave}
ref={editorRef}
/>
);Restoring via Ref
You can also restore state at any time using the imperative API:
editorRef.current?.setState(savedState);EditorState Shape
{
imageMeta: {
naturalWidth: number; // Original image width
naturalHeight: number; // Original image height
exifOrientation?: number; // EXIF orientation value
};
operations: OperationManifest; // Array of applied operations
viewport: {
zoom: number; // Current zoom level
panX: number; // Horizontal pan offset
panY: number; // Vertical pan offset
};
}Keyboard Shortcuts
Keyboard shortcuts are enabled by default. Disable them with ui={{ keyboardShortcuts: false }}.
| Shortcut | Action |
|-----------------------|-----------------------------|
| Ctrl/Cmd + Z | Undo |
| Ctrl/Cmd + Shift + Z | Redo |
| Ctrl/Cmd + Y | Redo (alternative) |
| + / = | Zoom in |
| - | Zoom out |
| H (hold) | Before/after comparison |
Viewport & Navigation
The editor provides a rich viewport with zoom, pan, and comparison features:
- Zoom in/out — via toolbar buttons, keyboard shortcuts, or programmatic API.
- Zoom to fit — fit the entire image in the viewport.
- Pan — via toolbar directional buttons.
- Before/after — hold
Hor use the toolbar button to toggle between the current and original image. - Grid overlays — enable with
ui={{ showGrid: true }}. Choose from"ruleOfThirds","goldenRatio","pixel", or"none".
Operation Types
All editing operations are represented as typed objects, making them serializable and inspectable.
// Crop
{ type: "crop", rect: { x, y, width, height }, refSize?: { width, height }, aspect?: string | null }
// Rotate
{ type: "rotate", angle: number, expandCanvas: boolean, background?: string | null }
// Flip
{ type: "flip", axis: "x" | "y" }
// Filter
{ type: "filter", id: string, params: Record<string, any>, version?: string }
// Draw
{ type: "draw", strokes: DrawStroke[], refSize: { width, height } }DrawStroke Shape
{
points: { x: number; y: number }[]; // Array of drawing points
color: string; // Brush color (hex)
lineWidth: number; // Brush size in pixels
opacity: number; // Brush opacity (0–1)
eraser: boolean; // Whether this stroke erases
}Exports
The package exports the following:
// Components
export { ImageEditor } // The main editor component (default export)
// Types
export type { EditorHandle } // Ref type for imperative API
export type { ImageEditorProps } // Component props type
export type { EditorState } // Serializable editor state
export type { Operation } // Union of all operation types
export type { OperationManifest } // Array of operations
export type { CropOperation } // Crop operation type
export type { RotateOperation } // Rotate operation type
export type { FlipOperation } // Flip operation type
export type { FilterOperation } // Filter operation type
export type { DrawOperation } // Draw operation type
export type { DrawStroke } // Individual draw stroke
export type { FilterDefinition } // Filter plugin definition
export type { FilterContext } // Context passed to filter functions
export type { FilterUiParam } // Filter UI parameter definition
export type { ToolDefinition } // Custom tool definition
export type { ToolId } // Built-in tool identifiers
export type { EngineOptions } // Engine configuration type
export type { DesignTokens } // Theme token type
export type { EditorStringKey } // i18n string key type
export type { SupportedLocale } // Built-in locale type ("en" | "pl")
export type { EngineApi } // Internal engine API type
// Filters
export { traceLinesFilter } // Built-in edge detection filter
// i18n
export { translations } // Built-in translation dictionaries { en, pl }Browser Support
| Browser | Version | |--------------------|----------| | Chrome / Edge | Latest | | Firefox | Latest | | Safari | Latest |
Required browser features:
- Canvas API
- ImageBitmap API
- ES2021+ JavaScript
Development
Building the Library
npm run build:libThis creates a dist/ folder with:
mui-image-editor.es.js— ES module buildmui-image-editor.cjs.js— CommonJS buildindex.d.ts— TypeScript declarations
Development Mode
npm run devOpens a test application with HMR at the Vite dev server.
Publishing to npm
# Simple publish
npm run publish:npm
# Interactive publish script
npm run publish:scriptLicense
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Support
For issues, questions, or feature requests, please open an issue on the GitHub repository.
