npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

straight-to-video

v0.0.10

Published

Browser-based, hardware-accelerated video upload optimization

Readme

straight-to-video

Certified Shovelware

straight-to-video optimizes video entirely in the browser using WebCodecs API. Files are remuxed & re-encoded to meet the requirements of the Instagram API, which is as good a lowest-common-denominator as any.

I'm not here to save the planet—I wrote this because I'm cheap and I was sick of waiting all day to upload 4K videos to my Rails app, only to have to pay Heroku tooth-and-nail to transcode those videos for me. That said, if everyone were to plug this into their HTML forms tomorrow, it'd save users and developers a gobsmacking amount of bandwidth and server costs.

Seriously, most off-iPhone videos are in the neighborhood of 90-95% smaller after running through straight-to-video optimization, sometimes shaving tens of minutes from the time it would take to upload at 30 Mbps.

Install

You can find straight-to-video on npm and its

npm install straight-to-video

Or if you're one of us Ruby on Rails weirdos:

bundle add straight_to_video

API

canOptimizeVideo

canOptimizeVideo(file) quickly validates that a File is a recognizable video and that the browser can encode it with WebCodecs. It does not perform any heavy work and does not estimate output size.

Returns an object with three fields only: { ok, reason, message }.

import { canOptimizeVideo } from 'straight-to-video'

const result = await canOptimizeVideo(file)
// Example results:
// { ok: true,  reason: 'ok', message: 'ok' }
// { ok: false, reason: 'probe-failed', message: '…error message…' }

optimizeVideo

optimizeVideo(file) will run your file through this AI-generated fever dream and it'll return a version that's downscaled to 1080p and ready to share, whether it needs to be remuxed, transcoded, or have a silent AAC track injected.

The method will generally fail silently without changing the file (worst-case, I just let users upload the same garbage to my server they always have).

import { optimizeVideo } from 'straight-to-video'

const result = await optimizeVideo(file)
// Example results:
// { changed: true,  file: File('my-clip-optimized.mp4') }
// { changed: false, file: File('image.png') }

registerStraightToVideoController

If you're looking to rig straight-to-video up with Stimulus, you can register the included controller by passing your Stimulus app and the Controller parent class to registerStraightToVideoController:

import { Application, Controller } from '@hotwired/stimulus'
import { registerStraightToVideoController } from 'straight-to-video'

const app = Application.start()
registerStraightToVideoController(app, { Controller })

This will register a controller named "straight-to-video" that will target one or more file inputs and handle video optimization during form submission.

More on that in the next section.

Integrating with Stimulus

I wrote straight-to-video to support video workflows for a couple Rails apps. Both apps use import maps and Stimulus, so the controller that's bundled with this package is how I use straight-to-video myself.

Here's how to configure it if you have a similar setup.

// app/javascript/controllers/index.js
import { application } from 'controllers/application'
import { Controller } from '@hotwired/stimulus'
import { registerStraightToVideoController } from 'straight-to-video'

registerStraightToVideoController(application, { Controller })

From there, simply add the straight-to-video controller to any of your forms that contain file inputs and flag the inputs for which you want to optimize any video files with the target fileInput:

<form data-controller="straight-to-video">
  <input data-straight-to-video-target="fileInput" type="file">
  <!-- The rest of your form -->
</form>

By default, this will automatically intercept form submission, optimize your file input(s), and then resubmit the form with optimized video(s).

(So it can run before Active Storage Direct Upload handles the document's submit event, the straight-to-video controller binds to the window's submit event.)

If you want to get a jump on things, you can also wire up the change event to optimize as soon as the user sets the file, so it's ready to upload as soon as submitted:

<input data-straight-to-video-target="fileInput" type="file"
  data-action="change->straight-to-video#change">

And if you have another controller that's interested in displaying progress of optimization or surfacing any errors, you can also bind to the controller's events:

  • progress - fired as optimization proceeds—this event's detail contains { progress } as an integer percent completion
  • done - fired after optimization finishes, with detail containing a boolean { changed }, indicating whether the file was optimized and swapped out
  • error - fired when optimization encounters an error, with detail containing { error } of the originating error

These might be wired up in the same form like this:

<form data-controller="straight-to-video progress-bar">
  <input data-straight-to-video-target="fileInput" type="file"
    data-action="change->straight-to-video#change
      straight-to-video:progress->progress-bar#update
      straight-to-video:done->progress-bar#finish">

  <!-- The rest of your form -->
</form>

Development

If you want to work on this code, install ffmpeg and the dependencies:

brew install ffmpeg
npm install

You can run the tests (which run against both webkit and Chrome) with:

# Open graphical browsers
./script/test

# Run headlessly
CI=true ./script/test

You can run the server at localhost:8080 (which hosts the demo site) with:

npm run dev