Repository navigation
Source Layout
This page is an annotated index of the source tree: one line per file under src/ and scripts/, grouped by directory. Use it to find where something lives. The Architecture, Recording Pipeline, Screenshot Pipeline and Upload Pipeline pages explain how the files work together. The index reflects the main branch; check the source tree when a file here is missing or new.
Imports use the @/ alias for src/, so @/lib/db is src/lib/db.ts.
The root holds configuration rather than code:
-
wxt.config.tssetssrcDir: 'src'and MV3 for both browsers, adds the React module and the Tailwind Vite plugin, and builds the manifest for Chrome or Firefox: name, description, permissions, optional upload permissions, minimum browser version, the options page, the Firefox add-on ID and the Chromekey. It loads.env.localitself to readWXT_EXTENSION_KEY. -
package.jsonholds the scripts (dev,build,zipand their:firefoxversions,compile,screenshots,showcase) and the version that Release Please bumps. -
.env.examplelists the upload services' build variables. Copy it to.env.local, which git ignores. See Development. -
PRIVACY.mdis the privacy policy that the OAuth consent screens link to. -
components.jsonconfigures the shadcn/ui CLI forsrc/components/ui/. -
CHANGELOG.mdis written by Release Please and bundled into the app for the home and changelog pages. -
public/icon/holds the 16, 32, 48 and 128 px icons thatscripts/make-icons.mjsdraws.
| File | Contents |
|---|---|
app.tsx |
App page shell: header, navigation, hash-route-to-page mapping, toaster |
env.d.ts |
Vite type reference and the WXT_GOOGLE_CLIENT_ID and WXT_DROPBOX_APP_KEY build variables |
WXT builds one manifest entry from each file or folder here.
| File | Contents |
|---|---|
background.ts |
Service worker in Chrome, background script in Firefox: opens the recorder window, takes screenshots, stops recordings from the toolbar, opens the home page on install and update |
popup/index.html |
HTML for the toolbar popup |
popup/main.tsx |
Mounts PopupPage with the global CSS |
app/index.html |
HTML for the app page (app.html) |
app/main.tsx |
Mounts App with the global CSS |
Each file is one screen. All but popup.tsx render inside the app page.
| File | Route | Contents |
|---|---|---|
recorder.tsx |
/ |
Recording options, countdown, live view, finished view; listens for stopRecording
|
videos.tsx |
/videos, /videos/<id>
|
Latest videos list with thumbnails and saved names, and detail: play, save or upload, uploads, make seekable, delete |
screenshots.tsx |
/screenshots, /screenshots/<id>
|
Screenshot list with quick download, copy and upload; detail page hosting the editor and revert |
player.tsx |
/player |
Plays a video file from disk and can make a WebM seekable |
settings.tsx |
/settings |
Every setting, camera and microphone permission check, camera overlay preview, Connections card |
home.tsx |
/home |
Welcome page with links to each section and the current release's notes |
changelog.tsx |
/changelog |
Parses the Release Please format of CHANGELOG.md and lists every release |
popup.tsx |
none | Toolbar popup: record buttons, screenshot buttons, app links |
Logic with no React in it, except where a file builds DOM elements to do its work.
| File | Contents |
|---|---|
annotate.ts |
Screenshot annotation model (Doc, Shape), rendering, pixelation and flattening |
capture.ts |
Camera and microphone streams, screen size cap, audio mixer, permission check, device list, CaptureError
|
compositor.ts |
Draws the screen and camera overlay onto the canvas that gets recorded |
compress.ts |
Compression presets, size estimates, re-encoding with Mediabunny |
db.ts |
IndexedDB schema (version 2) and access for recordings, chunks, screenshots and uploads, with retention limits |
download.ts |
downloadBlob, the app.html URL builder, opening the app in a tab |
formats.ts |
MIME type choice for MP4 and WebM, file names, duration and byte formatting |
messages.ts |
AppMessage union for runtime messages |
optimize.ts |
Writes a duration into WebM files so they can be seeked; probes the duration of files without one |
page-scripts.ts |
Functions injected into the captured tab: area picker and full-page scroll helpers |
screenshot.ts |
Visible, area and full-page capture in the background worker |
session.ts |
RecordingSession: opens streams, records, autosaves chunks, stops |
settings.ts |
Settings types, defaults, validation and localStorage persistence; drops system audio where the browser can't record it |
squircle.ts |
Squircle outline shared by the compositor and the settings preview |
thumbnail.ts |
makeThumbnail: a small JPEG of an early frame, for Latest videos |
ticker.ts |
Frame timer driven by Web Audio, so drawing continues in hidden windows |
toolbar.ts |
Toolbar badge, title and popup switching during countdowns and recordings |
utils.ts |
cn() class name helper (clsx with tailwind-merge) |
version.ts |
currentVersion() from the manifest |
Upload destinations and the code that runs uploads. The Upload Pipeline page explains them.
| File | Contents |
|---|---|
types.ts |
The Connector interface, OAuthConfig, Connection, UploadJob, UploadContext, UploadError and ReconnectNeeded
|
registry.ts |
CONNECTORS, the built-in destinations in display order, and lookups that include saved upload servers |
connections.ts |
Connected accounts in browser.storage.local, and useConnections()
|
auth.ts |
connect, disconnect and authorizedFetch: sign-in with launchWebAuthFlow, token renewal, optional permissions |
upload.ts |
startUpload, resume, retry and cancel: runs uploads with retries, records them in IndexedDB, live progress |
local.ts |
"This computer": a download through downloadBlob
|
google-drive.ts |
Google Drive connector: Screen Tools folder, share links, revoke |
google-drive/api.ts |
Drive API requests and error mapping to UploadError
|
google-drive/resumable.ts |
Drive resumable uploads in 8 MiB chunks |
dropbox.ts |
Dropbox connector: single or session uploads to the app folder, share links, revoke |
dropbox/api.ts |
Dropbox API requests, 429 waits and error mapping to UploadError
|
upload-server.ts |
Upload servers added by URL: the two-step upload and addUploadServer
|
What differs between Chrome and Firefox. Shared code imports platform from @/platform. See Architecture.
| File | Contents |
|---|---|
index.ts |
Exports platform, picked at build time from import.meta.env.FIREFOX
|
types.ts |
The Platform interface: capabilities, screen picker, browser-specific copy |
chrome.ts |
Screen capture through desktopCapture, with system and tab audio |
firefox.ts |
Screen capture through getDisplayMedia, without audio |
| File | Contents |
|---|---|
use-before-unload.ts |
Makes Chrome ask before the page closes while a flag is set |
use-busy.ts |
Shared flag for a recording in progress, which locks the navigation |
use-route.ts |
Hash router: useRoute() and navigate()
|
use-settings.ts |
useSettings(), which re-renders when settings change in any extension page |
use-uploads.ts |
useUploads(): a recording's or screenshot's upload rows, with live progress |
App-specific components. Generic primitives live in ui/.
| File | Contents |
|---|---|
choice-tiles.tsx |
Row of large single-choice tiles, used for capture and audio source |
confirm-dialog.tsx |
Delete confirmation and the unsaved-recording prompt |
icons.tsx |
MonitorCamera, a custom Lucide icon for screen plus camera; the Google Drive and Dropbox logos |
option-select.tsx |
Select built from a list of { value, label } options, with an optional icon each |
recorded-video.tsx |
Video player for a blob with custom controls: seek bar, skip, volume, speed, picture in picture, full screen, keyboard shortcuts |
save-video.tsx |
useSaveVideo() and the save dialog with destination, compression and upload progress; the large-file notice |
screenshot-editor.tsx |
Annotation editor: tools, undo history, download, copy, upload |
theme-provider.tsx |
Applies the light, dark or system theme as a dark class on <html>
|
upload-dialog.tsx |
Screenshot upload dialog, the share link switch, and useConnectedDestinations()
|
upload-list.tsx |
A recording's or screenshot's uploads: progress, links, Resume and Retry |
upload-servers.tsx |
Settings section for adding and removing upload servers |
upload-status.tsx |
Upload progress bar, the "Uploaded to …" toast, copy link and error wording |
shadcn/ui components in the base-nova style, built on Base UI (@base-ui/react), except card.tsx, label.tsx and sonner.tsx, which don't use it. The directory holds alert-dialog, badge, button, card, dialog, input, label, progress, radio-group, select, separator, slider, sonner (the toast container), switch, toggle, toggle-group and tooltip.
| File | Contents |
|---|---|
globals.css |
Tailwind v4 entry, theme colour variables for light and dark, including the record red |
Node scripts for the Chrome Web Store listing and the icons. None of them is part of the extension build. The listing screenshots guide covers running the capture script.
| File | Run with | Contents |
|---|---|---|
capture-screenshots.ts |
pnpm screenshots |
Builds the extension, loads it in headless Chromium with Playwright, seeds sample data, captures each view to out/screenshots/
|
listing-samples.ts |
imported | Made-up web pages that the capture script turns into sample screenshots and recordings |
build-showcase.ts |
pnpm showcase |
Turns the captures into listing images and promo tiles in out/showcase/, in the style of listing-image-style.md
|
make-icons.mjs |
node scripts/make-icons.mjs |
Draws the extension icon with no dependencies and writes public/icon/*.png
|
Using Screen Tools
- Installation and Updating
- Firefox
- Recording
- Screenshots
- Uploading
- Settings
- Troubleshooting and FAQ
- Privacy
How it works
Contributing