By the ZoomCap team.We make ZoomCap, which appears in this article. Prices and features were checked on each vendor's own site on September 29, 2026. Where we could not test a tool ourselves, we say so. How we test
Short answer
Reproduce the bug once, switch on Preserve log in DevTools, then record 30–90 seconds: the starting state, each step narrated, a pause on the failure, and what you expected. Attach the MP4 to a written report (template below) with the console error pasted as text.
The fastest way to make the trigger obvious: record with ZoomCap. It zooms in on your clicks and typing automatically, so the developer sees exactly what you pressed, and the recording is never uploaded, which matters when internal data is on screen. It's free to try in the browser with nothing to install, and $29 once for the full version. Pick something else only if you want console logs attached automatically or a hosted link with comments.
To record a bug report video, reproduce the bug once without recording so you know the exact steps, then open your browser's DevTools with Preserve log switched on. Record 30–90 seconds: where you start (URL, account, role), each step narrated slowly, a pause on the moment it breaks, and one sentence on what should have happened. Attach the MP4 to a written report with the environment, steps, expected and actual result, and the console error pasted as text. The video proves the bug; the text makes it searchable and fixable.
We make ZoomCap and use it for exactly this: showing what was clicked, zoomed in, without the video leaving your computer. The steps in this guide work with any recorder, and we say where ZoomCap does a step for you. Tracker limits and DevTools menu names come from each vendor's documentation, linked where we use them, checked in September 2026.
TL;DR
- A bug video replaces "can't reproduce", not the written report. Always pair it with text.
- Start from a known state, narrate each step, pause on the failure, and say what you expected.
- 30–90 seconds covers almost any single bug. Longer usually means two bugs, or unclear steps.
- Capture console errors and failed requests in DevTools. Paste errors as text, and share HAR files only when sanitized.
- Check for tokens, customer data and notifications before you record, and again before you share.
- GitHub accepts videos up to 10 MB in free-plan repositories and 100 MB in paid ones, so export short clips at 720p.
Who this is for
QA testers filing issues, support agents escalating a ticket to engineering, developers asking a teammate to look at something, product managers and designers reporting what they found in a review, and anyone who has been asked by a developer to "send a recording".
How to record a bug report video in seven steps
- Reproduce it once without recording and write the steps down. If you cannot reproduce it, see the FAQ below.
- Reset to a known starting state: reload the page, log in as the right role, load the data that triggers the bug.
- Open DevTools and switch on Preserve log in the Console and Network panels.
- Hide anything private: other tabs, notifications, secrets, customer data.
- Record 30–90 seconds, narrating each step and holding still on the failure.
- Trim and export an MP4, at 720p if it is going to GitHub.
- File the report with the template below, attach the video, and paste the console error as text.
What a developer needs from a bug video
A developer needs to make the bug happen on their own machine. That takes the exact steps from a known starting point, what you expected versus what happened, the environment (browser, OS, app version, account type), and any console or network errors. Video is the best way to show steps and the failure. It is bad at environment details and error text, which belong in writing.
| What they need | Why it matters | Best captured in |
|---|---|---|
| Starting state (URL, account, role, data) | Most "can't reproduce" replies come down to different state | First five seconds of video, and text |
| Exact steps | They have to follow them | Video, plus numbered text |
| Expected vs actual | Separates a bug from a misunderstanding of how it works | Say it on video, write it in text |
| Environment | Browser, OS, version and feature flags change behaviour | Text |
| Console errors | A stack trace often points at the broken line | Text: paste it, don't screenshot it |
| Failed network requests | Status code, endpoint and request ID point at the server side | Text, or a sanitized HAR file |
| When it happened | Lets someone find the matching server logs | Text, with timezone |
| Frequency | "Always" and "1 in 10" are debugged very differently | Text |
The 30–90 second structure
Keep a bug video to 30–90 seconds and one bug per video. Open on the starting state, perform each step slowly while you say it, stop and hold on the failure for two or three seconds, then say what you expected. If DevTools shows an error, end on it.
| Time | Beat | What you do | What you say (example) |
|---|---|---|---|
| 0:00–0:05 | Starting state | Show the URL, the account and any relevant setting | "Staging, logged in as an Editor, on the Shipments page." |
| 0:05–0:40 | Steps | One action at a time, slower than normal; keep the mouse still between steps | "I set the date filter to September. Now I click Export CSV." |
| 0:40–0:50 | Failure | Stop moving and hold on the broken state for 2–3 seconds | "The file downloads, but it's empty." |
| 0:50–1:00 | Expected | Point at where the right result should be | "It should contain the 38 shipments in this table." |
| 1:00–1:30 | Evidence | Switch to DevTools and hover the red line | "There's a TypeError in the console, and the export request returns a 400." |
Narrate like a pilot reading a checklist: what you are doing, then what you see. Keep the cursor still when you are not using it, because a cursor circling the screen makes it hard to tell what you actually clicked.
Should you narrate?
Yes, if you can. Saying "clicking Export, the file is empty, I expected 38 rows" removes most of the guesswork. If you cannot talk, for example in an open office or on a customer call, keep the video silent and put the steps and the expected result in the written report. Never add music.
Whole screen or just the window?
Just the window or tab where the bug happens, unless the bug involves something outside it, such as a download dialog, a second window or an operating system permission prompt. A smaller capture area gives bigger, more readable text and a smaller file.
A copy-paste bug report template
Paste this into your issue tracker, fill in every field, and attach the video. If you do not know a field, write "unknown" rather than deleting it; the gap is information too.
## [Area] Short description of what breaks
**Environment**
- App version / build / commit:
- URL or screen:
- Browser + version:
- OS + version:
- Device:
- Account, role, plan:
- Feature flags, locale, timezone:
**Steps to reproduce**
1.
2.
3.
**Expected result**
**Actual result**
**Frequency**
Always / Intermittent (__ of __ tries) / Once
**When it happened**
Date, time and timezone:
**Video**
[attached or linked]. The bug happens at __:__
**Console / network errors**
```
Paste the error text here (not a screenshot)
```
Failed request: [METHOD] [endpoint] -> [status], request ID:
**Workaround**
None / describe
**Impact**
Who is affected, how many users or ticketsFilled-in example (Harborline, a made-up logistics app)
## [Shipments] Export CSV downloads an empty file when a date filter is set
**Environment**
- App version: web build 4.18.2 (staging)
- URL: https://staging.harborline.example/shipments
- Browser: Chrome 152
- OS: macOS 26
- Device: MacBook, external 1440p display
- Account: qa-editor@harborline.example, Editor role, Team plan
- Feature flags: new-export-pipeline ON
**Steps to reproduce**
1. Open Shipments.
2. Set the date filter to 1 Sep - 30 Sep.
3. Click Export CSV.
**Expected result**
A CSV with the 38 shipments shown in the table.
**Actual result**
A CSV with a header row and no data. Without a date filter,
the export works.
**Frequency**
Always (5 of 5 tries)
**When it happened**
28 Sep, 14:12 CEST
**Video**
Attached (48 s). The empty file opens at 0:31.
**Console / network errors**
```
TypeError: Cannot read properties of undefined (reading 'map')
at buildRows (export.js:212)
```
Failed request: GET /api/shipments/export?from=2026-09-01 -> 400,
request ID: 7f3c-91ab
**Workaround**
Export without a filter and filter the spreadsheet.
**Impact**
Every Team-plan customer using date filters; 3 support tickets so far.On GitHub you can make this the default for new issues: save it as .github/ISSUE_TEMPLATE/bug_report.md with a front matter block on top. GitHub requires name and about for Markdown templates, and accepts optional keys such as labels (GitHub's issue template docs):
---
name: Bug report
about: Something is broken. Attach a short video if you can.
labels: bug
---Capture console and network errors
Open DevTools before you reproduce the bug and switch on Preserve log in both the Console and the Network panel, so a page reload does not wipe the evidence. Then reproduce. Copy the red console error as text, note the failed request's method, URL and status code, and export a sanitized HAR file only if a developer asks for one.
In Chrome
- Open the Console with Cmd+Option+J on a Mac or Ctrl+Shift+J on Windows and Linux.
- Open Console settings (the gear) and tick Preserve log.
- Switch to the Network panel and tick its own Preserve log checkbox. Disable cache is worth ticking too if the bug only happens for new visitors.
- Reproduce the bug. Failed requests show up in red.
- Right-click in the Console and choose Save as… to save every message to a
.logfile, or just copy the error text. - If a developer wants the network log, right-click the request list and choose Save all as HAR (sanitized), not the "with sensitive data" option.
Be careful with Copy as cURL. It is handy for developers, but the copied command includes your request headers, which can include cookies and authorization tokens. Menu names are from Google's Console and Network references.
Chrome vs Firefox (and Safari)
| Browser | Open the console | Keep logs across reloads | Export the network log |
|---|---|---|---|
| Chrome | Cmd+Option+J / Ctrl+Shift+J | Preserve log (Console settings and Network panel) | Save all as HAR (sanitized) |
| Firefox | Cmd+Opt+K / Ctrl+Shift+K | Persist Logs (Network Monitor menu) | Save All as HAR (treat it as containing cookies) |
Firefox names come from Mozilla's Network Monitor docs. Safari hides its developer tools until you enable them: Safari → Settings → Advanced → "Show features for web developers" (Apple's instructions).
Bonus: Chrome's Recorder panel for exact steps
Chrome DevTools also has a Recorder panel (More options → More tools → Recorder) that records your clicks as a replayable user flow and exports it as JSON or a Puppeteer script. Google's own docs point out that this is useful for bug reports, because a developer can replay your exact steps (Recorder reference). It is Chrome-only and marked as a preview feature. Use it alongside a video, not instead of one: the recording shows what went wrong, the flow shows how to get there.
Privacy checklist before you record (and before you share)
Before recording, close or hide anything that is not part of the bug: other tabs, notifications, password managers, API keys and real customer data. Before sharing, watch the whole video once at full size. HAR files and "Copy as cURL" output can contain session cookies and authorization headers, which let someone act as you.
Before you record
- Reproduce on a test account or staging with fake data whenever you can.
- Turn on Do Not Disturb and quit Slack and mail. A notification banner can put a customer's name in the corner of your video.
- Close unrelated tabs and hide the bookmarks bar.
- Close
.envfiles, terminals with tokens, cloud consoles and password-manager pop-ups. - Watch for autocomplete dropdowns in email fields and the address bar; they show history you did not mean to share.
- If DevTools is on screen, do not click into Application or Storage (cookies, tokens) or into request headers (authorization) while recording.
- If you are a support agent and must reproduce inside a customer's account, follow your company's access policy, get the customer's consent, and record only what the bug needs.
Before you share
- Watch it at full size, pausing wherever the page changes.
- Cut or crop anything that should not be there. ZoomCap has crop and cut but no blur tool, so if something sensitive sits in the middle of the frame, re-record. It is faster than masking every frame.
- Sanitize HAR files. Chrome offers a sanitized export, and Cloudflare's free HAR Sanitizer strips session cookies and tokens in your browser. Cloudflare built it after attackers used a session token taken from a HAR file in Okta's support system in October 2023 (Cloudflare's write-up).
- Check where it is going. An issue in a public repository is public, video included.
- If a secret appeared on screen, even for a frame, rotate it.
File size and format for issue trackers
Export an H.264 MP4. GitHub accepts .mp4, .mov and .webm videos up to 10 MB in repositories on a free plan and up to 100 MB on a paid plan, and recommends H.264 for compatibility. Jira Cloud's default limit is 1 GB per file, so size matters far less there. For GitHub, short clips at 720p are the way to stay under the limit.
| Tracker | Video limit (as of September 2026) | Notes |
|---|---|---|
| GitHub issues and pull requests | 10 MB in free-plan repositories; 100 MB in paid-plan repositories | .mp4, .mov, .webm; H.264 recommended. Images and GIFs: 10 MB. Other files: 25 MB. |
| Jira Cloud | 1 GB per file by default; admins can raise it to 2 GB | Free plans have 2 GB of total storage per app |
| Linear | We couldn't verify a published upload limit | Pasted YouTube, Loom and Descript links embed automatically |
Sources: GitHub's attachment docs, Atlassian's attachment settings and Linear's editor docs.
The 10 MB arithmetic
10 MB is 80 megabits. Spread over a 60-second video, that is an average of about 1.3 Mbps for picture and sound together; over 30 seconds, about 2.7 Mbps. A 720p recording of a mostly still interface can get there. A full-screen high-resolution recording with lots of scrolling usually cannot. To get under the limit:
- Record just the window, not the whole display.
- Trim to the starting state, the steps and the failure.
- Export at 720p.
- Still too big? Run it through our free video compressor, which works in your browser without uploading the file.
- Still too big? Split it into two issues if it is two bugs, or link to your team's file storage.
For why MP4 rather than MOV or WebM, see our video format guide.
Trim and zoom so the bug is visible
Trim everything before the starting state and after the evidence, but never cut between the action that triggers the bug and the failure, because the timing is often the clue. Zoom in on the element you click and on the result, so a developer watching in a small embedded player can see exactly what changed.
- Trim, do not speed up. Race conditions, debounce bugs and slow responses all depend on timing, and speeding the video up hides them. ZoomCap's speed setting applies to the whole video, so leave bug recordings at 1×.
- Zoom on the trigger. A full 1440p frame in an issue's inline player is too small to read. ZoomCap's CLI (macOS 15+ and Linux X11) tracks every click and zooms to it automatically, and redraws the cursor larger with an optional click sound, so there is no doubt which button was pressed. In browser recordings you place those zooms by hand on the timeline. Our guide to zooming in on a screen recording covers other tools.
- No recorder with zoom? On a Mac, the Screenshot app (Shift-Command-5) has a Show Mouse Clicks option under Options that draws a black circle around the pointer when you click (Apple's guide). On Windows 11, Snipping Tool records a selected area with Windows logo key + Shift + R (Microsoft's guide).
- Skip the styling. Backgrounds, padding and music make a demo look good and make a bug video smaller and noisier. Let the app fill the frame.
- Write the timestamp in the report: "fails at 0:31" saves the developer from scrubbing.
When a screenshot or text is enough
Use text when the bug is an error message or a crash log, an annotated screenshot when it is visual and static, and a video when the bug depends on a sequence, timing or motion. A live screen-share beats all three when the bug only happens on one person's machine and you need to try things together.
| Bug | Best format | Why |
|---|---|---|
| Typo, wrong colour, misaligned layout | Annotated screenshot | It is static; a screenshot is faster to read than a video is to scrub |
| An error message on screen | Text, plus a screenshot | Developers search for the exact wording in code and logs |
| Crash or exception with a stack trace | Text log | Every line matters and has to be copyable |
| A multi-step flow that breaks | Video plus written steps | The sequence is the bug |
| Flicker, animation glitch, drag and drop, focus or scroll jumps | Video | Only motion shows it |
| Intermittent bug | Video of one occurrence, plus frequency and logs | The video proves it exists; the logs explain it |
| Slow page | A performance trace or HAR file | Video shows that it is slow, not why |
| Only happens on one customer's machine | Live screen-share | You need to try things in real time |
Which recorder to use for bug videos
Why ZoomCap. The question developers ask most about a bug video is "what did you click?". On recordings made with npx zoomcap record (macOS and Linux X11), every click and typing burst becomes a zoom and the cursor is redrawn larger, with an optional click sound, so the trigger is unmistakable. It works for bugs outside a browser tab too: a desktop app, a CLI, an OS dialog. Everything is edited and encoded on your machine and never uploaded to us (see security), and you export an MP4 at 720p for GitHub's limit, or a GIF. The free browser recorder works on any OS, including Windows, with zooms you place by hand.
If you need something else: a purpose-built tool can do the DevTools section of this guide for you on web bugs. Jam, for example, is a Chrome extension that records the screen and keeps console logs, network requests, user events and device details with the recording (jam.dev). Website feedback widgets such as Marker.io send reports straight into Jira, GitHub, Linear and others. If you need a hosted link with comments and view notifications, Loom does that; we compare it in our Loom alternative for demos post.
| Tool | Price (checked Sep 2026) | Platforms | Local vs cloud | Captures console/network | Main tradeoff |
|---|---|---|---|---|---|
| ZoomCap | Free (2 watermarked exports/mo); $29 once or $12.49/mo | Browser recorder on any OS; CLI on macOS and Linux X11 | Local, never uploaded | No | Zooms on every click and typing burst (CLI); no share link and no blur tool |
| Built-in (Shift-Command-5, Snipping Tool) | Free | macOS; Windows 11 | Local | No | Nothing to install, but no zoom or trimming beyond basics |
| Jam | See Jam's pricing page | Chrome extension | Cloud | Yes, with the recording | Built for web bugs; browser tabs only |
| Loom | Free (25 videos per person, 5-minute limit, 720p); Business $18/user/mo | macOS, Windows, Chrome extension, iOS, Android | Cloud | No | A link with comments and view notifications; no zoom |
| OBS Studio | Free | Windows, macOS 12+, Linux | Local | No | Powerful capture, but setup first and no editor |
Loom's details are from its pricing page and Jam's from jam.dev; we haven't tested either hands-on for this guide.
Three real-world examples
A QA tester filing on GitHub
The team's repository is private on a free plan, so the video limit is 10 MB. The tester reproduces the export bug on staging with a QA account, records only the browser window with DevTools docked at the bottom, and exports 45 seconds at 720p. The issue uses the template, the console error is pasted as text, and the report says "empty file at 0:31". The developer reproduces it on the first try.
A support agent escalating a ticket
A customer writes in: "exports are broken". Rather than recording inside the customer's account, the agent recreates the same plan and settings on an internal test account and records there. The Jira issue gets the ticket ID, the customer's plan, how many similar tickets have come in, and the time of the customer's report with timezone. The customer also sent their own recording; the agent checks it for personal data before attaching it. With Jira's 1 GB default, file size is not the problem here. Privacy is.
Asking a customer to send a bug video
Give them the built-in shortcut for their system (Shift-Command-5 on a Mac, Windows logo key + Shift + R for Snipping Tool on Windows 11) and three instructions: start just before the problem, say what you expected to happen, and close anything private first. Tell them where the video will be stored and who will see it. Don't ask a customer to install a recorder for one bug. The built-in tools are enough, and ZoomCap's browser recorder also needs no install if they're in Chrome or Edge.
A developer asking a teammate
After rebasing onto main, the sidebar flickers on hover. The developer records 15 seconds, drops it in the team channel with the branch name and commit hash, and asks "seen this?". No template needed: the flicker is obvious in motion and impossible to describe in words.
Common mistakes
- A video with no text. It cannot be searched, skimmed or copied from.
- Starting mid-flow, so nobody knows the starting state.
- A cursor that never stops moving, so nobody can tell what was clicked.
- Recording a whole large display where the relevant button is a few pixels tall.
- Screenshots of console errors instead of the text.
- Several bugs in one video. One bug, one video, one issue.
- Cutting or speeding up between the trigger and the failure.
- Notifications left on, putting someone's message in the corner.
- Unsanitized HAR files or cURL commands pasted into a public issue.
- "It doesn't work" with no expected result. Say what should have happened.
Our recommendation
Write first, record second. Fill in the template, then record a 30–90 second video that proves the steps and shows the failure, with DevTools evidence at the end. The starting state, the narration and the text next to the video matter more than anything else.
For the recording itself, use ZoomCap. It answers the question developers ask most about bug videos, "what did you click?": on CLI recordings the editor zooms in on every click and redraws a cursor you can make bigger, so the trigger is unmistakable. Everything is processed on your machine, which matters when the screen has internal data on it; the video is never uploaded to us, and the data flow is on our security page. The limits, plainly: no hosted link, comments or automatic console capture (you export an MP4 and attach it), no blur tool, no Windows CLI (on Windows you place zooms by hand in browser recordings), and the Linux CLI records video only.
Try it free in the browser (2 exports a month with a small watermark), or record with npx zoomcap record on Pro ($12.49 a month) or Lifetime ($29 once), with a 14-day refund if it doesn't work for you (pricing, setup, docs). Pick something else only if you need console logs attached to the recording automatically (a bug-capture extension such as Jam) or a hosted link with comments (Loom).
Frequently asked questions
How do I record a bug report video on iPhone or Android?
On iPhone, swipe down from the top-right corner to open Control Center, tap the Screen Recording button, and wait for the three-second countdown; stop from the red indicator or Control Center, and the video lands in Photos. On Android, swipe down twice from the top, tap Screen record (add it with Edit if it is missing), and turn on the option to show touches so taps are visible.
What if the bug doesn't happen while I'm recording?
Keep recording for a few more attempts, then stop and write down how often it happens, for example 2 out of 10 tries, and the time of each occurrence with your timezone so someone can find the server logs. Leave Preserve log on in DevTools so the console error is kept even when the video misses the moment.
How do I share a bug video that's too big to attach?
Trim it to the steps and the failure, export at 720p, and run it through a video compressor. If it still does not fit, upload it to your team's file storage and link it from the issue, with access limited to people who should see it. Do not post a public link to a video that shows internal data.
Is a GIF okay for a bug report?
For a few seconds of visual glitch, yes. GitHub accepts GIFs up to 10 MB and shows them inline, and ZoomCap exports GIF as well as MP4 from the same edit. For anything longer, or anything that needs narration, use an MP4, because GIFs have no sound and get large quickly.
Is it safe to record a bug when internal data is on screen?
Only if you control where the file goes. Cloud recorders and bug-capture extensions upload the recording to their servers by design, which may or may not fit your policy. Built-in OS recorders, OBS and ZoomCap keep the file on your computer; ZoomCap records, edits and encodes locally and never uploads the video to us, as documented on our security page. Whatever you use, watch the video once at full size before sharing, and never attach an unsanitized HAR file.
Recording a demo rather than a bug? See how to record a product demo, with a script template and export settings per platform.
Record your next bug report
Record the bug free in your browser, with nothing to install, zoom in on the trigger and export an MP4 small enough for GitHub. For automatic zoom on every click, no watermark and unlimited exports, it's $29 once on the pricing page.