# ntsc-rs: a Rust VHS and NTSC effect for After Effects, Premiere, OpenFX and standalone use

> ntsc-rs reimplements the ntscqt composite-video simulator in multithreaded Rust, shipping as an After Effects, Premiere or OpenFX plugin and as a standalone application. It is a rough port, not an exact one, and the README is explicit about that.

**ntsc-rs/ntsc-rs** — Free, open-source VHS effect. Standalone application + plugin (After Effects, Premiere, and OpenFX).

- Repository: https://github.com/ntsc-rs/ntsc-rs
- Website: https://ntsc.rs
- Stars: 2,597 · Forks: 61
- Language: Rust
- License: NOASSERTION
- Published: 2026-09-28 · Updated: 2026-09-28 · Language: en
- Canonical page: https://hysenlabs.com/projects/ntsc-rs-ntsc-rs

## What ntsc-rs actually emulates, and who reaches for it

ntsc-rs is a video effect that emulates NTSC and VHS artifacts. That sentence is the whole product statement, and it is worth unpacking because the two terms cover different failure modes of analogue video. NTSC is the colour encoding: luma and chroma share a channel, and the separation is imperfect. VHS is the tape format: low bandwidth, head switching, dropout. A tool that emulates both is really a chain of signal-processing passes, and the art is in how those passes are ordered and tuned.

The audience is narrow and identifiable. Editors who need a period look for a music video or a title sequence want it as a plugin inside the editor they already use, which is why After Effects, Premiere and OpenFX are the three plugin targets. People who want to process a file without opening an editor want the standalone application. Anyone expecting a one-click filter preset will find the parameter surface larger than they want.

The lineage matters for expectations. ntsc-rs is a rough Rust port of ntscqt, a PyQt GUI for ntsc, which is itself a Python port of composite-video-simulator. The README states plainly that it is not an exact port, that some processing passes have visibly different results, and that new passes have been added. So the output is in the same family as the Python tools, not a bit-identical reproduction.

## Why the port is in Rust, and what that changes about the mechanism

The README gives the motivation directly: reimplementing the image processing in multithreaded Rust allows it to run at (mostly) real-time speeds. That is the entire architectural argument, and it is a reasonable one. The reference implementations are Python and PyQt, and per-pixel composite-video simulation is exactly the workload where an interpreted language becomes the bottleneck.

The workspace layout reflects a multi-target build rather than a single binary. Cargo.toml declares members as crates/* plus xtask, with resolver 2. The xtask member is the conventional Rust pattern for a build or packaging helper, and the presence of about.toml alongside it suggests generated metadata for the distributable builds. The crates directory is where the shared image-processing code and the individual front ends would live, though the README does not enumerate them.

The practical consequence of a shared core plus several front ends is that the plugin and the standalone application should produce the same look for the same settings. That is an inference from the layout, not a documented guarantee. If you are building a pipeline where the standalone renders a reference clip and the plugin renders the final, test one clip through both before you trust it.

One detail in Cargo.toml is worth noting for anyone compiling from source: the bench profile sets debug = full. That keeps debug symbols in benchmark builds, which is a deliberate choice for profiling rather than a default. It tells you the maintainers profile the processing passes.

## Installing ntsc-rs and running a first clip

The README points to the releases page for the latest version, and then to the documentation for how to run it. There is no cargo install line in the README, so the intended path is a downloaded release artifact rather than a build from crates.io. Start by fetching the release that matches your platform.

```bash
# Download the release for your platform from:
# https://github.com/valadaptive/ntsc-rs/releases
```

The README carries one hard warning about the standalone application on Linux: it will not work properly unless you install all of the GStreamer packages listed in the documentation. This is not a soft recommendation. GStreamer is the media backend, and a partial install tends to fail at decode or encode rather than at launch, which makes it a confusing first-run experience.

```bash
# Linux: install the GStreamer packages listed at
# https://ntsc.rs/docs/standalone-installation/
# before running the standalone application.
```

For plugin use, the same release page carries the After Effects, Premiere and OpenFX builds. Install the one for your host using the host's normal plugin installation procedure, then apply the effect to a clip and open its parameter panel. The README does not document the individual controls, so expect to work from the on-screen labels and from experimentation rather than from a parameter reference.

The first thing to check on any new machine is whether playback keeps up. The claim in the README is (mostly) real-time, and the qualifier is doing work: a long clip at high resolution is where the gap between mostly and fully shows up. If your first render is slower than you expected, that is the documented behaviour, not a broken install.

## The rough-port caveat is the real limitation

Most effect tools have a limitation you discover by using them. ntsc-rs has one printed in the README. It is not an exact port of ntscqt, some processing passes have visibly different results, and some new passes have been added. If you are matching a look that was built in ntscqt, you cannot assume the same settings produce the same frames. You will be re-tuning.

The second limitation is the real-time qualifier. The README says mostly real-time, which is honest and also a warning. Multithreading buys throughput, not determinism, and the passes in a composite-video simulation are not uniformly expensive. A clip that plays back smoothly can still stall on a longer timeline or a higher resolution.

The third is platform friction. Linux is the only platform the README singles out as needing extra packages, and it needs them for the standalone application specifically. That asymmetry is a real cost for anyone standardising on Linux workstations.

Where ntsc-rs is the wrong tool: if you need a deterministic, reproducible transform that you can hash and diff, a signal-emulation effect with visibly different passes from its reference implementation is the wrong choice. If you need a clean digital glitch rather than an analogue one, this is also the wrong family of tool, since the artifacts it produces are specifically those of NTSC colour encoding and VHS tape.

## ntsc-rs compared with the ntscqt and ntsc lineage it came from

The honest alternative is not a different commercial plugin. It is the stack ntsc-rs was ported from: ntscqt, the PyQt GUI for ntsc, which in turn is a Python port of composite-video-simulator. The difference in approach is speed against fidelity. The Python tools are the reference behaviour; ntsc-rs is the fast reimplementation, and the README concedes the two diverge on some passes.

That makes the choice concrete. If your priority is matching existing ntscqt output, or you want the original pass definitions as the source of truth, stay with ntscqt. If your priority is working inside After Effects, Premiere or an OpenFX host at something close to real time, ntsc-rs is the one that runs there. The Python tools are not plugin-shaped, and ntsc-rs is.

There is a second axis worth naming: ntsc-rs adds passes the originals do not have. That cuts both ways. You get looks the Python stack cannot produce, and you lose the ability to treat the Python stack as an oracle for every setting in the panel.

## Maintenance, licensing and what upgrading costs you

The repository is not archived, and the last push was on 2026-09-21. Releases are frequent rather than annual: v0.9.6 and v0.9.5 both landed on 2026-09-05, and v0.9.4 before that on 2026-03-18. The version numbers are still in the 0.9 series, which is the useful signal here. Pre-1.0 software can change parameter behaviour between minor releases, and for an effect tool a parameter change is an output change. Pin the version you ship with.

MAINTAINING.md at the repository root is the file to read before you plan to depend on this long term. Its contents are not reproduced in the README, so treat it as required reading rather than an assumption.

Licensing needs care because the repository carries three licence files: LICENSE-APACHE-2.0, LICENSE-ISC and LICENSE-MIT. The metadata reports the licence as NOASSERTION, meaning no single identifier was asserted. Multiple permissive licences in one tree is a common Rust arrangement, but which one covers the artifact you redistribute is not something the README resolves. Check the individual crate manifests and the release you download, and get your own advice if you are shipping commercially. This is not legal advice.

## Conclusion

Adopt ntsc-rs if you want a VHS or NTSC look inside After Effects, Premiere or an OpenFX host, or you want a standalone binary for batch work, and you can live with a port whose processing passes differ visibly from the original. Do not adopt it if you need frame-exact parity with ntscqt output, or if you are on Linux and will not install the GStreamer packages the documentation lists. Before committing, verify two things: that your host loads the plugin build, and whether the repository's LICENSE-ISC and LICENSE-MIT files or the LICENSE-APACHE-2.0 file is the one that applies to the artifact you ship.

## FAQ

### Is ntsc-rs open source?

Yes. The repository ships source and carries LICENSE-APACHE-2.0, LICENSE-ISC and LICENSE-MIT files at its root. The licence metadata is reported as NOASSERTION rather than a single identifier, so check which file applies to the artifact you redistribute.

### How does ntsc-rs work?

It emulates NTSC and VHS video artifacts through a chain of image-processing passes. The README states that reimplementing that processing in multithreaded Rust lets it run at mostly real-time speeds, whereas the ntscqt and ntsc implementations it derives from are Python.

### How to install ntsc-rs?

Download the latest version from the releases page, then follow the documentation for how to run it. On Linux the standalone application will not work properly unless you install all of the GStreamer packages listed in that documentation.

### Is ntsc-rs free?

The project describes itself as free and open source, and the repository contains Apache-2.0, ISC and MIT licence files. There is no pricing or paid tier mentioned in the README.

### Is ntsc-rs safe to download?

The README directs users to the GitHub releases page at github.com/valadaptive/ntsc-rs/releases, and the homepage is ntsc.rs. Those are the two sources named in the project's own documentation. Nothing in the README describes additional distribution channels.

### Can I use ntsc-rs in DaVinci Resolve?

The README lists After Effects, Premiere and OpenFX as the plugin targets, plus a standalone application. OpenFX is the plugin format Resolve hosts, but the README does not name Resolve or confirm a tested Resolve build, so verify it in your own host before relying on it.

## Sources

- [Issues](https://github.com/ntsc-rs/ntsc-rs/issues)
- [ntsc-rs/ntsc-rs on GitHub](https://github.com/ntsc-rs/ntsc-rs)
- [Project website](https://ntsc.rs)
- [README](https://github.com/ntsc-rs/ntsc-rs/blob/main/README.md)
- [Releases](https://github.com/ntsc-rs/ntsc-rs/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/ntsc-rs-ntsc-rs
