Video Explorer is a small local web app for browsing videos from any folder on your machine. It serves a fullscreen-style masonry gallery, lets you sort and filter by filename prefix, and only auto-plays previews for videos that are currently visible on screen.
- Load any local folder by pasting its absolute path into the home page.
- Browse videos in a gapless masonry layout.
- Sort by name, modified time, or file size.
- Filter by
starts withand use the custom autocomplete list. - Toggle bookmarks from the video title overlay and persist them in local SQLite storage.
- Filter the grid to show only bookmarked videos.
- Show file metadata on hover without cluttering the grid.
- Cache detected video aspect ratios in
localStorageto reduce layout shifts. - Serve video files through range-enabled media endpoints for browser seeking.
.mp4.webm.ogg.mov.m4v.mkv.avi.wmv.flv
- Node.js 22+ recommended
- A modern desktop browser
No external dependencies are required.
npm startOr:
node server.jsThen open:
http://127.0.0.1:3210
- Enter a local folder path such as
C:\Users\username\Videos. - The app calls
GET /api/videos?folder=.... - The server scans only the top-level files in that folder, joins bookmark state from
data/bookmarks.sqlite, and returns metadata plus media URLs. - Bookmark changes are sent to
PUT /api/bookmarks. - The client renders the result into a masonry grid and lazy-starts preview playback only for visible items.
The server supports these environment variables:
PORT: main app server port. Default is3210.MEDIA_PORTS: comma-separated media server ports. Example:4001,4002,4003MEDIA_SERVER_COUNT: number of media ports to create whenMEDIA_PORTSis not set. Default is32.
If MEDIA_PORTS is not provided, the app starts media servers on sequential ports after the main port.
With the default settings, PORT=3210 creates media servers on 3211 through 3242.
Query parameters:
folder: absolute folder path
Response shape:
{
"folder": "C:\\Users\\username\\Videos",
"count": 2,
"videos": [
{
"name": "clip_001.mp4",
"relativePath": "clip_001.mp4",
"extension": ".mp4",
"size": 1234567,
"modifiedAt": "2026-03-08T00:00:00.000Z",
"isBookmarked": false,
"url": "http://127.0.0.1:3211/api/video?folder=...&file=clip_001.mp4"
}
]
}Request body:
{
"folder": "C:\\Users\\username\\Videos",
"file": "clip_001.mp4",
"isBookmarked": true
}Response shape:
{
"folder": "C:\\Users\\username\\Videos",
"file": "clip_001.mp4",
"isBookmarked": true
}Query parameters:
folder: absolute folder pathfile: file name inside that folder
Notes:
- Supports
GETandHEAD - Supports single-range requests for browser seeking
- Returns
404for missing files and416for invalid ranges
.
|-- public/
| |-- app.js
| |-- index.html
| `-- styles.css
|-- server.js
`-- README.md
- The selected folder path is saved in
localStorageundervideo-explorer:last-folder. - Video aspect ratios are cached in
localStorageundervideo-explorer:video-ratios. - Bookmarks are stored on the server in
data/bookmarks.sqlite. - The current implementation does not scan subdirectories recursively.
