<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: dev truth</title>
    <description>The latest articles on DEV Community by dev truth (@dev_truth_f4c8f876c).</description>
    <link>https://dev.to/dev_truth_f4c8f876c</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4103468%2Ffd90d42c-4591-4127-bd4c-2121991bb6a8.png</url>
      <title>DEV Community: dev truth</title>
      <link>https://dev.to/dev_truth_f4c8f876c</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dev_truth_f4c8f876c"/>
    <language>en</language>
    <item>
      <title>A floor plan is more than pixels: getting DXF exports to preserve meaning</title>
      <dc:creator>dev truth</dc:creator>
      <pubDate>Sun, 13 Sep 2026 14:22:42 +0000</pubDate>
      <link>https://dev.to/dev_truth_f4c8f876c/a-floor-plan-is-more-than-pixels-getting-dxf-exports-to-preserve-meaning-1kmg</link>
      <guid>https://dev.to/dev_truth_f4c8f876c/a-floor-plan-is-more-than-pixels-getting-dxf-exports-to-preserve-meaning-1kmg</guid>
      <description>&lt;p&gt;A wall can look right in a browser and still arrive in CAD at the wrong size. The difficult part of an export feature is preserving what the geometry means.&lt;/p&gt;

&lt;p&gt;I’m building FloorDraft, a manual 2D floor-plan editor. These are concrete details from its current exporter, plus a small acceptance checklist you can adapt for another drawing application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep three scales separate
&lt;/h2&gt;

&lt;p&gt;There are three different quantities involved: the relationship between drawing coordinates and real dimensions, the viewport zoom, and the scale used to print the result. Only the first belongs in a model-to-CAD conversion. Panning or zooming the view should never change the exported length of a wall.&lt;/p&gt;

&lt;p&gt;FloorDraft stores a millimetres-per-pixel calibration alongside the design. At the DXF boundary, it divides that calibration by 1, 10 or 1000 for millimetres, centimetres or metres. The resulting multiplier is applied to geometry, while the file’s unit setting is updated to match.&lt;/p&gt;

&lt;p&gt;For example, a 320-coordinate-unit line with a calibration of 12.5 mm per unit represents 4000 mm. Its exported length should therefore be 4000 in a millimetre file, 400 in a centimetre file, or 4 in a metre file. Merely changing the unit metadata while leaving the coordinates unchanged does not preserve this contract.&lt;/p&gt;

&lt;p&gt;Text height and dimension offsets need the same attention. A 100 mm annotation height becomes 0.1 units in a metre-based drawing. Geometry can be correct while annotations become enormous if they cross a different conversion path.&lt;/p&gt;

&lt;h2&gt;
  
  
  Treat the vertical-axis change as geometry
&lt;/h2&gt;

&lt;p&gt;The exporter maps a point to &lt;code&gt;(x * scale, -y * scale, 0)&lt;/code&gt;. Negating the vertical coordinate bridges the editor’s downward axis and the CAD drawing’s upward axis.&lt;/p&gt;

&lt;p&gt;That reflection affects more than endpoints. FloorDraft also negates furniture insertion angles. Door arcs calculate their angles using the reflected vertical difference and choose the short sweep. Reflecting a centre point but keeping an unconverted rotation can leave an object in the right place with the wrong orientation.&lt;/p&gt;

&lt;p&gt;A plain rectangular room is a weak visual fixture for this. Use something asymmetric: a door near one end of a wall and a rotated piece of furniture. Then check hinge position, opening direction and rotation in the receiving application.&lt;/p&gt;

&lt;h2&gt;
  
  
  A door symbol does not necessarily cut a wall
&lt;/h2&gt;

&lt;p&gt;The data relationship matters. In FloorDraft, an opening associated with a wall contributes an interval that is removed from the wall geometry during export. A free opening is exported as a symbol and produces a warning; it does not automatically cut the wall behind it.&lt;/p&gt;

&lt;p&gt;That distinction is useful for editing, but it must survive the handoff. Otherwise a user sees a door on screen and reasonably assumes there is also an opening in the exported wall.&lt;/p&gt;

&lt;p&gt;Before export, the current checks reject a non-positive or non-finite calibration, a missing referenced wall, linked openings outside their wall, and overlapping openings on the same wall. Estimated dimensions and free openings are warnings rather than silent claims of accuracy.&lt;/p&gt;

&lt;p&gt;This separates two questions: can the geometry be exported coherently, and how much should the recipient trust its measurements? A calibrated reference still needs on-site verification.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verify distance, structure and appearance separately
&lt;/h2&gt;

&lt;p&gt;For a compact acceptance fixture, I would use one known-length wall, a linked door, a free opening and a rotated furniture object. Then check:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Distance:&lt;/strong&gt; export in mm, cm and m; the known wall has the same physical length in each receiving document.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structure:&lt;/strong&gt; inspect wall outlines and the linked opening, rather than only checking that a door symbol exists.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Orientation:&lt;/strong&gt; verify the hinge and rotated furniture against the source design.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Readability:&lt;/strong&gt; inspect text and dimension sizes, not just wall coordinates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Warnings:&lt;/strong&gt; confirm estimated dimensions remain identified in the output.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;View independence:&lt;/strong&gt; change viewport zoom and export again; model geometry should remain equivalent even if file metadata differs.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These are suggested acceptance checks, not a claim that every CAD application has been tested. A parser can verify numbers, but opening the fixture in the application your recipient uses catches practical interoperability problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make the handoff understandable to the user
&lt;/h2&gt;

&lt;p&gt;A PNG shares appearance. An image-based PDF packages that appearance as a document. DXF provides geometry for continuing in CAD. Those are different deliverables, so the interface and help text should explain which job each format serves.&lt;/p&gt;

&lt;p&gt;For the user-facing version of these checks, I put together &lt;a href="https://floordraft.online/en/guides/export-floor-plan-to-dxf" rel="noopener noreferrer"&gt;FloorDraft’s DXF export guide&lt;/a&gt;, including units, layers and a sample file to try in the receiving software. Editing is free without an account; free PNG, PDF and DXF exports require Google sign-in.&lt;/p&gt;

&lt;p&gt;The question I now use when reviewing an exporter is: which meaning can this file lose while still looking plausible? For a floor plan, units, opening relationships and measurement confidence are good places to start.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclosure: prepared with AI assistance and checked against the current exporter and product documentation.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>showdev</category>
    </item>
    <item>
      <title>A waveform is not a silence detector: building browser audio edits</title>
      <dc:creator>dev truth</dc:creator>
      <pubDate>Sun, 06 Sep 2026 15:59:19 +0000</pubDate>
      <link>https://dev.to/dev_truth_f4c8f876c/a-waveform-is-not-a-silence-detector-building-browser-audio-edits-2c2c</link>
      <guid>https://dev.to/dev_truth_f4c8f876c/a-waveform-is-not-a-silence-detector-building-browser-audio-edits-2c2c</guid>
      <description>&lt;p&gt;A waveform is a useful overview of a recording. It is a poor source of truth for deciding which samples to delete. A display can normalize a quiet file until it looks loud, or compress several seconds into one bar. Feeding those bars into a detector would make presentation choices affect the edit.&lt;/p&gt;

&lt;p&gt;This is an implementation case study from my project, AudioCut. An AI agent drafted this article from the current decoding, analysis, interval-removal and export code. The numerical example below also appears in an existing unit test; the limitations are part of the implementation, not benchmark claims.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Keep analysis data separate from display data
&lt;/h2&gt;

&lt;p&gt;AudioCut analyzes decoded audio in 20 ms windows. Each window gets an RMS value: square the samples, average them, then take the square root. The implementation accumulates the squared samples across all channels before taking that average.&lt;/p&gt;

&lt;p&gt;The interface has a different job. It reduces the analysis to 180 display bars, takes the maximum window level within each bar, normalizes the bars against their visual peak, and applies a small minimum height so the waveform remains visible.&lt;/p&gt;

&lt;p&gt;Those transformations are useful for a chart. They discard information that the detector needs. Normalization removes the absolute level relationship, and aggregation reduces time resolution. The detector therefore consumes the original window-level array, not the displayed waveform.&lt;/p&gt;

&lt;p&gt;This also makes a useful architectural boundary: changing the chart's bar count should not change the removal intervals.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Define quietness and duration independently
&lt;/h2&gt;

&lt;p&gt;The detector converts the selected dB threshold to linear amplitude with &lt;code&gt;10 ** (thresholdDb / 20)&lt;/code&gt;. At -40 dB, that threshold is 0.01. A window qualifies when its RMS is at or below that value.&lt;/p&gt;

&lt;p&gt;Duration is a separate rule. The minimum number of consecutive windows is &lt;code&gt;ceil(minimumSilence / windowSeconds)&lt;/code&gt;, with a lower bound of one. A 0.5-second minimum therefore requires 25 consecutive 20 ms windows. A 0.2-second quiet run should not qualify just because it is very quiet.&lt;/p&gt;

&lt;p&gt;The implementation tracks the start of each quiet run and commits it when a louder window arrives. It also flushes the pending run at the end of the array. Without that final step, trailing silence would disappear from the detector's results.&lt;/p&gt;

&lt;p&gt;There is a stereo tradeoff here. Combining squared samples avoids cancellation between opposite-polarity channels, which can happen if channels are summed first. But a silent channel still lowers the combined RMS relative to measuring the active channel alone. A detector that must protect speech present in any channel may need a different aggregation rule, such as the maximum of per-channel RMS values. That would be a design change, not the current behavior.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Padding changes the deletion interval
&lt;/h2&gt;

&lt;p&gt;A detected quiet run is not yet the range that should be removed. AudioCut moves its start forward by the padding and its end backward by the same amount. Both endpoints are clamped to the media duration. The remaining deletion must span at least one analysis window.&lt;/p&gt;

&lt;p&gt;An existing regression fixture makes this concrete:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;50 windows at amplitude 0.001, followed by 10 windows at 0.5.&lt;/li&gt;
&lt;li&gt;Window duration: 0.02 seconds; total duration: 1.2 seconds.&lt;/li&gt;
&lt;li&gt;Threshold: -40 dB; minimum quiet duration: 0.5 seconds.&lt;/li&gt;
&lt;li&gt;Padding: 0.1 seconds at each end.&lt;/li&gt;
&lt;li&gt;Expected deletion: 0.1 to 0.9 seconds, or 0.8 seconds removed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Notice the order: the minimum-duration check applies to the quiet run before padding. Padding then decides how much of that run survives around the join. These settings answer different questions and should not be collapsed into one vaguely named sensitivity slider.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Keep a removal plan before copying samples
&lt;/h2&gt;

&lt;p&gt;The detector returns ordered time ranges. The processing stage derives the complementary ranges to keep, converts their boundaries to sample frames, and copies each channel into a new audio buffer in sequence.&lt;/p&gt;

&lt;p&gt;That separation makes the math easier to inspect than deleting samples during detection. The original decoded buffer remains available, and the output can be encoded independently. In this implementation, the result is a newly encoded MP3.&lt;/p&gt;

&lt;p&gt;There are practical limits. Detection has window-level resolution; rounding an endpoint to a sample frame does not recover information that the analysis never measured. The copy path also concatenates the retained ranges without a crossfade. Padding can preserve some breathing room, but it does not guarantee an inaudible join. Listening around cuts remains necessary.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Budget for decoded audio, not the compressed file
&lt;/h2&gt;

&lt;p&gt;A small compressed input can expand into a large PCM buffer. Before allocating that buffer, the code estimates &lt;code&gt;duration × sampleRate × channels × 4&lt;/code&gt; bytes for Float32 samples.&lt;/p&gt;

&lt;p&gt;For example, ten minutes of stereo audio at 48 kHz requires 230,400,000 bytes, about 220 MiB, for one decoded buffer alone. That is an arithmetic example, not a supported-duration promise. Decoder chunks, the edited buffer and encoding also consume memory. A check on the first buffer is a guardrail, not a measurement of peak memory use.&lt;/p&gt;

&lt;p&gt;Likewise, recognizing an MP4 container does not establish that its audio track can be decoded. The input path checks the available audio tracks and the selected track's decoding support before processing it. Video input produces audio output; this pipeline does not edit the picture.&lt;/p&gt;

&lt;h2&gt;
  
  
  A small regression checklist
&lt;/h2&gt;

&lt;p&gt;The existing audio-math test file passes five tests, including the padding fixture and rejection of a short quiet run. Those tests establish specific cases, not complete audio quality or browser compatibility.&lt;/p&gt;

&lt;p&gt;Useful additional cases for an audio-editing pipeline include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quiet runs at the beginning and end of a recording.&lt;/li&gt;
&lt;li&gt;Padding that consumes the entire candidate interval.&lt;/li&gt;
&lt;li&gt;Speech in only one stereo channel.&lt;/li&gt;
&lt;li&gt;A silent file and a file with no qualifying gaps.&lt;/li&gt;
&lt;li&gt;Changing waveform display resolution without changing detected intervals.&lt;/li&gt;
&lt;li&gt;Listening to the exported file around every join, alongside numerical duration checks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a concrete interface to the controls discussed here, &lt;a href="https://audiocut.online/en/silence-remover" rel="noopener noreferrer"&gt;AudioCut's Silence Remover&lt;/a&gt; exposes threshold, minimum duration and padding, then creates a separate MP3 for preview and download. Start with a short recording you have permission to edit.&lt;/p&gt;

&lt;p&gt;The broader lesson is to keep three things distinct: measurements of the source, the plan for changing it, and the picture used to explain that plan. Each layer can then be checked against its own requirements.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>architecture</category>
    </item>
    <item>
      <title>A PDF preview is a rendering contract: lessons from a Japanese worksheet tool</title>
      <dc:creator>dev truth</dc:creator>
      <pubDate>Sun, 06 Sep 2026 14:19:52 +0000</pubDate>
      <link>https://dev.to/dev_truth_f4c8f876c/a-pdf-preview-is-a-rendering-contract-lessons-from-a-japanese-worksheet-tool-hbp</link>
      <guid>https://dev.to/dev_truth_f4c8f876c/a-pdf-preview-is-a-rendering-contract-lessons-from-a-japanese-worksheet-tool-hbp</guid>
      <description>&lt;p&gt;A browser preview can look correct while the downloaded PDF breaks a word across pages, changes a glyph, or exports an older edit. For a handwriting worksheet, those are functional bugs: the spacing and character shapes are the product.&lt;/p&gt;

&lt;p&gt;This is an implementation case study from my project, 漢字ドリル (Kanji Drill), a Japanese handwriting worksheet generator. This article was drafted by an AI agent from the project's implementation; the concrete design choices below come from its layout, preview, export and storage code.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Give both renderers the same document
&lt;/h2&gt;

&lt;p&gt;The app first turns a draft into a layout document. Each page contains positioned cells, text baselines and optional vector paths. The document also records its revision and the font version used to build it.&lt;/p&gt;

&lt;p&gt;The screen renders that model as SVG with a 210 × 297 viewBox. The PDF renderer consumes the same page objects and converts millimetres to points using 72 / 25.4. It does not ask the browser to wrap the text again.&lt;/p&gt;

&lt;p&gt;This makes a 20 mm writing cell a physical measurement. Resizing the preview changes its screen scale, not the PDF geometry. With 12 mm margins on each side of A4, the available width is 186 mm: nine complete 20 mm cells fit, while a tenth does not.&lt;/p&gt;

&lt;p&gt;The useful separation is between deciding where content belongs and drawing it. Once pagination is part of the shared model, a renderer should not invent another line break.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Define what must stay together
&lt;/h2&gt;

&lt;p&gt;A single-character exercise and a name exercise have different pagination rules.&lt;/p&gt;

&lt;p&gt;For individual characters, a row is a useful unit. For a name or word, the indivisible unit is one complete repetition, which may occupy several rows. At 24 mm per cell, seven characters fit across the 186 mm content width. A 20-character sequence therefore needs three rows for each complete repetition.&lt;/p&gt;

&lt;p&gt;If the remaining page space cannot hold those three rows, move the entire repetition to the next page. Otherwise the learner gets the beginning of a name on one sheet and its ending on another.&lt;/p&gt;

&lt;p&gt;That rule belongs in the layout builder. It should not depend on which PDF viewer or browser happens to print the document.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Treat old output as a different version
&lt;/h2&gt;

&lt;p&gt;Font loading and PDF generation are asynchronous. Editing can continue while either operation is running.&lt;/p&gt;

&lt;p&gt;The draft carries a revision number that changes with edits. The preview is eligible for export only when its revision matches the current draft and validation succeeds. During an update, the previous preview may remain visible, but it is marked as previous output and cannot be downloaded as though it were current.&lt;/p&gt;

&lt;p&gt;The PDF export also checks whether its revision is still current while processing pages and around the final save. A stale export is discarded. Merely disabling the download button after it is clicked would not handle an edit made during generation.&lt;/p&gt;

&lt;p&gt;Japanese input adds another boundary: do not validate half-finished IME composition as final text. The preview hook waits until composition finishes and the text settles before rebuilding.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. A font family name is not enough
&lt;/h2&gt;

&lt;p&gt;The regular preview draws glyph outlines from the actual font asset, and PDF export embeds that asset. This avoids relying on a fallback font that looks acceptable on screen but has a different shape or width in the file.&lt;/p&gt;

&lt;p&gt;This implementation embeds the full Klee One font rather than a subset because its export path encountered missing composite glyphs with subsetting. That is a project-specific tradeoff, not a claim that all Japanese fonts require full embedding. The cost is a larger font payload; the benefit is preserving the checked glyph mapping.&lt;/p&gt;

&lt;p&gt;Font checks should inspect the final asset. The project's tests check real glyphs for the 1,026 grade-listed kanji and inspect the embedded font stream in a generated PDF. Those checks complement visual review; they cannot establish whether a worksheet is pedagogically appropriate.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Make persistence a separate decision
&lt;/h2&gt;

&lt;p&gt;A reusable layout does not necessarily need reusable personal text. Saving settings defaults to excluding the practice text, title and instruction. Including those fields is an explicit choice.&lt;/p&gt;

&lt;p&gt;Storage errors are surfaced without disabling worksheet generation. Restored content is validated again against the current settings and font. Local storage is useful for repeat work, but it is neither cross-device sync nor permanent backup.&lt;/p&gt;

&lt;p&gt;The same boundary applies to export names: the filename uses a timestamp instead of a learner's name. Keeping PDF creation local also does not mean the whole website makes no network requests; static assets and visit analytics are separate concerns.&lt;/p&gt;

&lt;h2&gt;
  
  
  A small regression checklist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Change the text while export is running: the old file must not be offered as the current result.&lt;/li&gt;
&lt;li&gt;Use a multirow sequence near a page boundary: one repetition must remain intact.&lt;/li&gt;
&lt;li&gt;Resize the preview: physical PDF cell sizes must stay constant.&lt;/li&gt;
&lt;li&gt;Restore an old template: validate it against current rules.&lt;/li&gt;
&lt;li&gt;Deny local storage: generation must still work.&lt;/li&gt;
&lt;li&gt;Compare the downloaded PDF with the preview using the same input and font asset.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a concrete example, the &lt;a href="https://kanjirenshu.com/kanji/" rel="noopener noreferrer"&gt;Kanji Drill worksheet editor&lt;/a&gt; exposes the cell size, tracing and preview controls discussed here. Start with 山川日月, then change one setting at a time. The interface is in Japanese.&lt;/p&gt;

&lt;p&gt;The design question I would carry to another document tool is simple: which layer owns geometry, and how do you prove that every output belongs to the user's current edit?&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>architecture</category>
    </item>
    <item>
      <title>What Actually Happens When Whisper Runs in Your Browser?</title>
      <dc:creator>dev truth</dc:creator>
      <pubDate>Wed, 02 Sep 2026 01:57:23 +0000</pubDate>
      <link>https://dev.to/dev_truth_f4c8f876c/what-actually-happens-when-whisper-runs-in-your-browser-51m0</link>
      <guid>https://dev.to/dev_truth_f4c8f876c/what-actually-happens-when-whisper-runs-in-your-browser-51m0</guid>
      <description>&lt;p&gt;A “browser-based transcription tool” can mean two very different things.&lt;/p&gt;

&lt;p&gt;In one version, the browser is only an upload form. Your recording travels to a server, the server runs a speech model, and the browser receives the result.&lt;/p&gt;

&lt;p&gt;In the other version, the browser does the actual inference. The media is decoded on the device, a speech model runs locally, and the transcript remains in browser storage until the user exports it.&lt;/p&gt;

&lt;p&gt;Those two architectures may look similar on the surface, but their privacy boundaries, performance constraints, and failure modes are very different. Here is the practical pipeline behind the second approach.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The application still has to arrive over the network
&lt;/h2&gt;

&lt;p&gt;“Local processing” does not mean “nothing uses the network.”&lt;/p&gt;

&lt;p&gt;The browser must first download the application code. A first transcription run also needs the selected Whisper model. Depending on the implementation, fonts, analytics scripts, and other static resources may be requested too.&lt;/p&gt;

&lt;p&gt;The important distinction is not whether the network exists. It is whether the selected recording and resulting transcript are sent to a transcription backend.&lt;/p&gt;

&lt;p&gt;A useful product should explain that boundary directly instead of reducing it to a “100% offline” badge.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The browser decodes the media
&lt;/h2&gt;

&lt;p&gt;Speech models expect audio samples, not an MP4, MOV, WebM, or compressed audio container.&lt;/p&gt;

&lt;p&gt;The browser therefore has to inspect the selected file, find the audio track, and decode it into a representation the model can consume. This step can fail before inference even starts. A familiar file extension does not guarantee that the codec inside the file is supported by the current browser.&lt;/p&gt;

&lt;p&gt;That is why a robust error message should distinguish between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a file the browser cannot decode;&lt;/li&gt;
&lt;li&gt;a model that failed to load;&lt;/li&gt;
&lt;li&gt;a compute backend that failed to initialize; and&lt;/li&gt;
&lt;li&gt;an inference job that ran out of memory.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Treating every failure as “transcription failed” makes local tools much harder to debug.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Inference should not freeze the interface
&lt;/h2&gt;

&lt;p&gt;Whisper inference is compute-heavy. Running it directly on the main JavaScript thread would compete with rendering, progress updates, buttons, and text editing.&lt;/p&gt;

&lt;p&gt;A Web Worker provides a separate execution context for model loading and inference. The page can send the worker a transcription job, receive model-download and segment-progress events, and keep the interface responsive enough to cancel or recover.&lt;/p&gt;

&lt;p&gt;A worker is not a performance shortcut by itself. The same CPU or GPU still does the work. Its main value is isolation: expensive model work does not have to monopolize the UI thread.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. WebAssembly and WebGPU solve different problems
&lt;/h2&gt;

&lt;p&gt;A browser-local Whisper tool commonly offers two compute paths.&lt;/p&gt;

&lt;h3&gt;
  
  
  WebAssembly
&lt;/h3&gt;

&lt;p&gt;WebAssembly is the compatibility-first option. It runs through the browser’s CPU-oriented runtime and works across a broader range of devices. It is a sensible default when the hardware is unknown or WebGPU is unavailable.&lt;/p&gt;

&lt;p&gt;The tradeoff is throughput. A larger model or a long recording may take significant time, especially on a low-power laptop or mobile device.&lt;/p&gt;

&lt;h3&gt;
  
  
  WebGPU
&lt;/h3&gt;

&lt;p&gt;WebGPU lets supported browsers use compatible graphics hardware for computation. On the right desktop setup it can improve throughput, but support depends on the browser, operating system, driver, and GPU.&lt;/p&gt;

&lt;p&gt;WebGPU is not a universal “fast mode.” Initialization can fail, memory pressure can still matter, and a larger model may still be a poor fit for the device.&lt;/p&gt;

&lt;p&gt;A practical strategy is simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start with WebAssembly when compatibility matters most.&lt;/li&gt;
&lt;li&gt;Try WebGPU on a supported desktop when local inference is too slow.&lt;/li&gt;
&lt;li&gt;Fall back to WebAssembly if WebGPU initialization or inference fails.&lt;/li&gt;
&lt;li&gt;Reduce the model size before assuming the entire workflow is broken.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This &lt;a href="https://whisperwebfree.com/blog/webgpu-vs-webassembly-whisper" rel="noopener noreferrer"&gt;WebGPU vs WebAssembly guide for local Whisper transcription&lt;/a&gt; includes a compact comparison and troubleshooting checklist.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Model size is part of the UX
&lt;/h2&gt;

&lt;p&gt;Tiny, Base, and Small Whisper models do not only differ in accuracy. They also change:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the first-download size;&lt;/li&gt;
&lt;li&gt;memory use;&lt;/li&gt;
&lt;li&gt;initialization time;&lt;/li&gt;
&lt;li&gt;inference speed; and&lt;/li&gt;
&lt;li&gt;the likelihood that the job fits comfortably on the device.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The “best” model is therefore contextual. A smaller quantized model can be a better default because it gets a first-time user to a transcript with less waiting and lower memory pressure. A larger model can remain an explicit choice for devices that can handle it.&lt;/p&gt;

&lt;p&gt;Progress reporting should separate model download from transcription. Otherwise a user cannot tell whether the system is fetching hundreds of megabytes, preparing the runtime, or actually processing audio.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Local history is still persistent data
&lt;/h2&gt;

&lt;p&gt;Once transcription finishes, the application needs somewhere to keep the result. IndexedDB is a natural browser storage layer for transcripts, timestamps, and task metadata.&lt;/p&gt;

&lt;p&gt;This creates a useful privacy property: the transcript can remain in the current browser rather than being attached to an online account.&lt;/p&gt;

&lt;p&gt;It also creates responsibilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;shared browser profiles may expose local history to other people using the profile;&lt;/li&gt;
&lt;li&gt;clearing site data can remove the history;&lt;/li&gt;
&lt;li&gt;device backups may copy browser data;&lt;/li&gt;
&lt;li&gt;exported TXT, JSON, SRT, or VTT files leave the browser’s storage boundary; and&lt;/li&gt;
&lt;li&gt;local processing does not replace recording consent or organizational policy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;“Not uploaded to the transcription service” is valuable, but it is not the same as “impossible for the data to leave the device.”&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Long recordings need a different memory strategy
&lt;/h2&gt;

&lt;p&gt;Decoding an entire long recording into memory can be wasteful or simply fail.&lt;/p&gt;

&lt;p&gt;A large-file workflow can inspect the duration, divide the audio timeline into manageable sections, decode and transcribe them in order, and combine text and timestamps only after all sections finish.&lt;/p&gt;

&lt;p&gt;That approach reduces peak working memory, but it introduces new UX constraints. The device must remain awake, partial progress may belong only to the current tab, and a refresh or browser shutdown may require restarting the unfinished job.&lt;/p&gt;

&lt;p&gt;A credible local tool should disclose those constraints before the user commits an hour-long recording to the process.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to evaluate in any browser transcription tool
&lt;/h2&gt;

&lt;p&gt;Before trusting the “local” label, ask five questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Does the selected media go to a remote API?&lt;/li&gt;
&lt;li&gt;Where does the speech model run?&lt;/li&gt;
&lt;li&gt;What does the browser still download?&lt;/li&gt;
&lt;li&gt;Where is the completed transcript stored?&lt;/li&gt;
&lt;li&gt;What happens after a refresh, cache clear, or export?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The answers reveal more than a privacy slogan. They describe the real data path, the performance model, and the points where a user can lose work.&lt;/p&gt;

&lt;p&gt;Browser-local transcription is not automatically the right architecture for every team. Cloud services remain useful for collaboration, server-side queues, speaker diarization, and processing that must continue after a laptop closes. But when the goal is to transcribe a recording on the current device with fewer data handoffs, modern browser APIs make that a practical option rather than a demo.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>privacy</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
