LabyStudio/paintdotjs

paint.js is a proof-of-concept, cross-platform raster graphics editor written in JavaScript. It’s a port of Paint.NET v3.36.7, bringing the best Windows painting tool to macOS, Linux, and the web via Electron and the browser.

JavaScript

47

131 commits

updated Oct 12, 2026

See the code

See what people are saying

SourceMessageScoreDate

Your /r/javascript recap for the week of October 05 - October 11, 2026 (r/javascript)

**Monday, October 05 - Sunday, October 11, 2026** ###Top Posts | score | comments | title & link | |--|--|--| | 251 | [86 comments](/r/javascript/comments/1x1lw8s/deno_is_joining_cloudflare_we_will_support_the/) | [Deno is joining Cloudflare - "We will support the Deno runtime for another year…

1

Oct 12, 2026

I spent almost 3 years porting Paint.NET from C# to JavaScript (r/javascript)

A bit of background on how I built this: When I switched to Linux, Paint.NET was one of the Windows apps I missed the most, so I started porting the old open-source C# version (3.36.7) to JavaScript back in 2024, while recreating the UI based on the newer 5.x versions. I went through the original…

39

Oct 11, 2026

README

header.png

paint.js is an unofficial, proof-of-concept, cross-platform JavaScript port of the Windows only raster graphics editor Paint.NET by Rick Brewster. This port is available for the web and as an Electron desktop application.

Its core editing model is based on Paint.NET 3.36.7, the last version released under the original MIT-compatible license, while the current interface and behavior follow Paint.NET v5.1.12+.

Why?

Paint.NET is one of the best image editors available on Windows, combining powerful features with a simple, intuitive interface. After switching to Linux, it became the application I missed most and one I had relied on every day. I have been developing paint.js since February 2024, with the goal of bringing that familiar editing experience to Linux, macOS, and the web.

License

Desktop application

Web application

Installation

Web

Use paint.js directly at paintjs.net. No installation is required.

Arch Linux

Install paintdotjs-bin from the AUR with an AUR helper, for example:

yay -S paintdotjs-bin

During installation, the AUR package fetches the required artwork and translations from the official Paint.NET download.

Flatpak

Download the latest .flatpak bundle from GitHub Releases, then install it with:

flatpak install --user ./paintdotjs-*-linux-x86_64.flatpak

The bundle uses the Freedesktop runtime from Flathub, but paint.js itself is installed directly from the downloaded file.

macOS

Download the latest universal .dmg from GitHub Releases, open it, and drag paint.js into the Applications folder.

The macOS app fetches the required artwork and translations from the official Paint.NET download on first launch.

Differences from Paint.NET

paint.js is largely feature-complete and closely reproduces the Paint.NET experience, but there are still some additions and limitations worth noting.

Added in paint.js

  • Runs on macOS, Linux, Windows, and the web through a shared JavaScript codebase, with an Electron desktop application for a more native experience.
  • A Fonts settings page lets you add font files by picker or drag and drop, preview installed fonts, and remove individual fonts or clear them all. Added fonts are stored locally and are available in the Text tool.
  • A searchable Keyboard settings page lets you rebind, clear, and reset keyboard shortcuts.
  • Interface, canvas, tool, pen, window, and dialog preferences are stored locally and restored across sessions.
  • The deployed web version can work offline and provides browser-oriented file, clipboard, and drag and drop workflows.

Missing or limited compared with Paint.NET

  • Chromium is the supported browser family. Firefox and Safari are not regularly tested, and their file-system and clipboard capabilities differ.
  • Open Recent, scanner/camera acquisition, and color-profile commands are not implemented yet.
  • Native Paint.NET plugins and file-type plugins cannot be loaded.
  • Manual GPU/device selection and direct advanced-color management are not implemented.
  • Very large documents, large-radius effects, and complex selections may still be slower or more memory-intensive than in Paint.NET.
  • Some browser functionality requires HTTPS or localhost, including parts of the clipboard, file-system, and offline-app support.

Image formats

FormatPaint.NET openPaint.NET savepaint.js openpaint.js saveImportant differences
Paint.NET (.pdn)YesYesLimitedLimitedpaint.js supports bitmap layers and basic layer properties, with a maximum of 64 layers when saving. History, selections, plugin data, and some newer PDN features are not preserved.
PNGYesYesYesYes—
JPEG (.jpg, .jpeg, .jpe)YesYesYesYes—
JPEG XL (.jxl)YesYesYesYes—
AVIFYesYesYesYes—
HEIC/HEIFWith the Windows codecWith the Windows codecYesNoThe bundled paint.js codec can decode these files but cannot encode them.
WebPYesYesYesYes—
DDSYesYesYesYespaint.js saves uncompressed 32-bit images only.
TIFF (.tif, .tiff)YesYesYesYespaint.js saves uncompressed RGBA images only.
GIFYesYesYesYespaint.js saves a single static, palette-based image only.
BMPYesYesYesYespaint.js saves 32-bit images with alpha only.
TGAYesYesYesYespaint.js saves uncompressed 32-bit images only.
JPEG XR (.jxr, .wdp, .wmp)YesYesLimitedNopaint.js can open RGB images with 8-bit, 16-bit, or 32-bit floating-point channels but cannot save JPEG XR.

Animated and multi-page files are imported and exported as a single static image in paint.js.

Development

Development requires Node.js 22 or newer. Install the dependencies first:

npm ci

Run the web version

Run the development build in watch mode:

npm run web-watch

In a second terminal, start a local web server and open http://127.0.0.1:8773/:

npx http-server . -p 8773

Do not open index.html directly from the filesystem because browser security restrictions disable required functionality.

Run the Electron app

npm run app

The repository does not redistribute Paint.NET's modern artwork and translations because they are not part of the MIT-compatible Paint.NET 3.36.7 source release on which this project is based. On the first build, paint.js fetches the required assets from the official Paint.NET download. This lets the interface follow Paint.NET v5.1.12+ without redistributing those files in this repository.

Build the Flatpak

The Flatpak manifest is in flatpak/net.paintjs.Paintjs.yml. It builds the checked-out paint.js source with pinned dependencies, bundles the assets needed for offline use, and keeps the application inside the Flatpak sandbox.

flatpak-builder --user --install --force-clean \
  --install-deps-from=flathub flatpak-build flatpak/net.paintjs.Paintjs.yml
flatpak run net.paintjs.Paintjs

License

paint.js is licensed under the MIT License. See the attribution notice for details about Paint.NET and the JavaScript port.

electron
javascript
paint
paintdotnet

LabyStudio/paintdotjs

paint.js is a proof-of-concept, cross-platform raster graphics editor written in JavaScript. It’s a port of Paint.NET v3.36.7, bringing the best Windows painting tool to macOS, Linux, and the web via Electron and the browser.

JavaScript

47

131 commits

updated Oct 12, 2026

See the code

See what people are saying

SourceMessageScoreDate

Your /r/javascript recap for the week of October 05 - October 11, 2026 (r/javascript)

**Monday, October 05 - Sunday, October 11, 2026** ###Top Posts | score | comments | title & link | |--|--|--| | 251 | [86 comments](/r/javascript/comments/1x1lw8s/deno_is_joining_cloudflare_we_will_support_the/) | [Deno is joining Cloudflare - "We will support the Deno runtime for another year…

1

Oct 12, 2026

I spent almost 3 years porting Paint.NET from C# to JavaScript (r/javascript)

A bit of background on how I built this: When I switched to Linux, Paint.NET was one of the Windows apps I missed the most, so I started porting the old open-source C# version (3.36.7) to JavaScript back in 2024, while recreating the UI based on the newer 5.x versions. I went through the original…

39

Oct 11, 2026

README

header.png

paint.js is an unofficial, proof-of-concept, cross-platform JavaScript port of the Windows only raster graphics editor Paint.NET by Rick Brewster. This port is available for the web and as an Electron desktop application.

Its core editing model is based on Paint.NET 3.36.7, the last version released under the original MIT-compatible license, while the current interface and behavior follow Paint.NET v5.1.12+.

Why?

Paint.NET is one of the best image editors available on Windows, combining powerful features with a simple, intuitive interface. After switching to Linux, it became the application I missed most and one I had relied on every day. I have been developing paint.js since February 2024, with the goal of bringing that familiar editing experience to Linux, macOS, and the web.

License

Desktop application

Web application

Installation

Web

Use paint.js directly at paintjs.net. No installation is required.

Arch Linux

Install paintdotjs-bin from the AUR with an AUR helper, for example:

yay -S paintdotjs-bin

During installation, the AUR package fetches the required artwork and translations from the official Paint.NET download.

Flatpak

Download the latest .flatpak bundle from GitHub Releases, then install it with:

flatpak install --user ./paintdotjs-*-linux-x86_64.flatpak

The bundle uses the Freedesktop runtime from Flathub, but paint.js itself is installed directly from the downloaded file.

macOS

Download the latest universal .dmg from GitHub Releases, open it, and drag paint.js into the Applications folder.

The macOS app fetches the required artwork and translations from the official Paint.NET download on first launch.

Differences from Paint.NET

paint.js is largely feature-complete and closely reproduces the Paint.NET experience, but there are still some additions and limitations worth noting.

Added in paint.js

  • Runs on macOS, Linux, Windows, and the web through a shared JavaScript codebase, with an Electron desktop application for a more native experience.
  • A Fonts settings page lets you add font files by picker or drag and drop, preview installed fonts, and remove individual fonts or clear them all. Added fonts are stored locally and are available in the Text tool.
  • A searchable Keyboard settings page lets you rebind, clear, and reset keyboard shortcuts.
  • Interface, canvas, tool, pen, window, and dialog preferences are stored locally and restored across sessions.
  • The deployed web version can work offline and provides browser-oriented file, clipboard, and drag and drop workflows.

Missing or limited compared with Paint.NET

  • Chromium is the supported browser family. Firefox and Safari are not regularly tested, and their file-system and clipboard capabilities differ.
  • Open Recent, scanner/camera acquisition, and color-profile commands are not implemented yet.
  • Native Paint.NET plugins and file-type plugins cannot be loaded.
  • Manual GPU/device selection and direct advanced-color management are not implemented.
  • Very large documents, large-radius effects, and complex selections may still be slower or more memory-intensive than in Paint.NET.
  • Some browser functionality requires HTTPS or localhost, including parts of the clipboard, file-system, and offline-app support.

Image formats

FormatPaint.NET openPaint.NET savepaint.js openpaint.js saveImportant differences
Paint.NET (.pdn)YesYesLimitedLimitedpaint.js supports bitmap layers and basic layer properties, with a maximum of 64 layers when saving. History, selections, plugin data, and some newer PDN features are not preserved.
PNGYesYesYesYes—
JPEG (.jpg, .jpeg, .jpe)YesYesYesYes—
JPEG XL (.jxl)YesYesYesYes—
AVIFYesYesYesYes—
HEIC/HEIFWith the Windows codecWith the Windows codecYesNoThe bundled paint.js codec can decode these files but cannot encode them.
WebPYesYesYesYes—
DDSYesYesYesYespaint.js saves uncompressed 32-bit images only.
TIFF (.tif, .tiff)YesYesYesYespaint.js saves uncompressed RGBA images only.
GIFYesYesYesYespaint.js saves a single static, palette-based image only.
BMPYesYesYesYespaint.js saves 32-bit images with alpha only.
TGAYesYesYesYespaint.js saves uncompressed 32-bit images only.
JPEG XR (.jxr, .wdp, .wmp)YesYesLimitedNopaint.js can open RGB images with 8-bit, 16-bit, or 32-bit floating-point channels but cannot save JPEG XR.

Animated and multi-page files are imported and exported as a single static image in paint.js.

Development

Development requires Node.js 22 or newer. Install the dependencies first:

npm ci

Run the web version

Run the development build in watch mode:

npm run web-watch

In a second terminal, start a local web server and open http://127.0.0.1:8773/:

npx http-server . -p 8773

Do not open index.html directly from the filesystem because browser security restrictions disable required functionality.

Run the Electron app

npm run app

The repository does not redistribute Paint.NET's modern artwork and translations because they are not part of the MIT-compatible Paint.NET 3.36.7 source release on which this project is based. On the first build, paint.js fetches the required assets from the official Paint.NET download. This lets the interface follow Paint.NET v5.1.12+ without redistributing those files in this repository.

Build the Flatpak

The Flatpak manifest is in flatpak/net.paintjs.Paintjs.yml. It builds the checked-out paint.js source with pinned dependencies, bundles the assets needed for offline use, and keeps the application inside the Flatpak sandbox.

flatpak-builder --user --install --force-clean \
  --install-deps-from=flathub flatpak-build flatpak/net.paintjs.Paintjs.yml
flatpak run net.paintjs.Paintjs

License

paint.js is licensed under the MIT License. See the attribution notice for details about Paint.NET and the JavaScript port.

electron
javascript
paint
paintdotnet

Significant stargazers

Michael Scherbakow

42 followers · starred Oct 2026