Category: Coding Tools

  • Bionic Reading Converter: Speed-Read Any Text [2026]

    Bionic Reading Converter: Speed-Read Any Text [2026]

    TL;DR: Bionic reading is a typographic technique that bolds the first 1–4 letters of every word (“fixation points”) with the rest in normal weight. The premise: bold lead-letters give the eye anchor points so it can skim faster while inferring the rest of each word. Reader response is mixed — some people read 20–30% faster, others find it visually noisy. Our free bionic reading converter applies the formatting to any text with adjustable fixation ratio, then exports HTML, PDF, or copies rich-text to clipboard. Browser-only.

    Bionic Reading was popularised by a 2022 viral demo from a Swiss company. The idea: human reading speed is bottlenecked by the eye’s saccadic jumps between words, and bolding the leading letters gives the eye a clearer landing target — increasing reading speed without sacrificing comprehension. Some readers describe it as a noticeable boost, especially for skimming long technical articles; others call it visually distracting and slower. Like all reading aids, mileage varies.

    Our bionic reading converter applies the formatting to any text you paste, with a slider for fixation ratio (how many letters to bold). Output is rich HTML you can copy-paste into a Doc or Notion, or export as PDF/HTML for printing. The conversion runs entirely in your browser — your text never leaves your device. This guide explains how the algorithm works, the research-vs-marketing claims, and when bionic formatting is genuinely useful (and when it gets in the way).

    How the formatting works (the algorithm)

    Word length Letters bolded (default) Example
    1–3 letters 1 an, the, it
    4 letters 2 that, from
    5–6 letters 2 or 3 strong, beyond
    7–10 letters 3 or 4 fixation, reading
    11+ letters 4 or 5 technology, cognition

    The fixation ratio slider lets you adjust this aggressiveness. Lower (e.g., bolding only ~30% of each word) is subtler; higher (~60%+) is heavier and may feel cluttered. The original Bionic Reading uses ~50% by default.

    Does it actually help reading speed?

    The marketing claim is “up to 200% faster”. The peer-reviewed research is more modest. A 2022 study by the University of Cambridge found no statistically significant reading-speed improvement across 200 subjects. Independent psycholinguists have pushed back on the broader claims. So the honest answer: bionic reading doesn’t make most people faster.

    What it does seem to help with, anecdotally:

    • ADHD readers: some users with ADHD report that bionic format helps them maintain focus on long passages — bold lead-letters work as visual anchors that re-engage attention.
    • Skimming. When the goal isn’t full comprehension but skimming for keywords, bionic format helps pull the gaze across faster.
    • Cognitive load on dense material. For some readers, the visual structure makes paragraph-shaped walls of text less daunting.
    • Dyslexic readers. Reports are mixed — some dyslexic readers find it helpful, others find the visual noise harder to parse.

    If you’re considering bionic formatting as an accessibility feature, test with the actual readers it’s meant to help — don’t assume it works for everyone.

    How to convert text to bionic reading

    1. Open the bionic reading converter
    2. Paste your text in the input
    3. Adjust the fixation slider (default 50% — half the letters of each word bolded)
    4. Pick output format: HTML (paste into Doc or Notion), Rich text (clipboard), or PDF
    5. Click Copy or Download

    The HTML output (and why rich-text matters)

    Plain text can’t carry the bold formatting; you need rich HTML. The converter outputs HTML like this:

    <p>
      <strong>Bo</strong>ld 
      <strong>th</strong>e 
      <strong>fir</strong>st 
      <strong>hal</strong>f 
      <strong>of</strong> 
      <strong>ev</strong>ery 
      <strong>wor</strong>d.
    </p>

    Pasting this into Notion, Google Docs, or any rich-text editor preserves the bold formatting. Pasting into a plain-text editor strips the HTML and you get the original text without bolding. Use the “Copy as Rich Text” button in our tool — it puts both HTML and plain-text versions on the clipboard, and the destination app picks whichever it supports.

    Common gotchas

    • Hyphenated words become odd. “Self-aware” with bionic formatting becomes “Self-aware”, which most readers find harder, not easier. Our converter has an option to skip words shorter than 4 characters and to treat hyphenated words as a unit.
    • Numbers and code snippets shouldn’t be bionic-formatted. “404 not found” with bolding becomes confusing. The converter detects numeric words and code-fenced text (markdown `code`) and skips them by default.
    • Doesn’t work in pure plain text. Email-only readers, plain-text terminals, and any non-rich-text destination strip the formatting. Use HTML or PDF for digital sharing.
    • Don’t mass-convert your reading list. The format works for some content (dense technical articles) and against others (poetry, fiction, copy-edited prose where typography matters). Convert per-document, not by default.
    • Accessibility considerations. Bold text increases visual noise for some users with low vision or specific reading disabilities. Always offer a toggle to view the original — never force bionic formatting on readers without consent.
    • Trademark issue. “Bionic Reading” is a trademarked name owned by Bionic Reading AG. Open-source equivalents go by names like “OpenDyslexic Reading” or just “fixation reading” to avoid the trademark — our tool uses the term “bionic reading” as the descriptive technique name, not as the brand.

    When NOT to use bionic reading

    For literary or carefully-written prose where the rhythm of the language matters, bionic formatting interferes with the reading experience the author intended. For poetry — never use it; the visual structure of the poem is part of the meaning. For language learners reading in a foreign language, bionic formatting can confuse word-segmentation as you’re still building your mental dictionary. For ebook readers (Kindle, Kobo), most don’t preserve rich-text bolding consistently — convert just before reading, not as a permanent storage format. For accessibility certifications (WCAG), bold-heavy content can fail readability thresholds.

    Frequently asked questions

    Does bionic reading actually make me read faster?

    Studies are mixed. A 2022 Cambridge study found no significant speed improvement across the general population. Anecdotally, some readers — especially those with ADHD — report subjective benefit. Try it on your own typical reading material and decide.

    Can I use this for ebooks?

    Yes — convert a chapter to PDF or HTML, then transfer to your ebook reader. Most readers preserve bold formatting in EPUB and PDF. Kindle’s older firmware sometimes drops bold; test on your specific device.

    Is this the same as the trademarked “Bionic Reading”?

    It’s the same technique. “Bionic Reading” is a trademark of Bionic Reading AG; we use the term descriptively (like “spell check” or “track changes”). The algorithm is straightforward and unpatented; many open-source implementations exist.

    Can I customise how aggressive the bolding is?

    Yes — the fixation ratio slider goes from very subtle (~30% of each word bolded) to heavy (~70%). Default is 50%, matching the original tool. Lower ratios are easier on the eyes; higher ratios produce stronger anchor points for skimming.

    Is my text uploaded?

    No. The converter runs in your browser. Pasted text never leaves your device — useful when converting drafts, internal documents, or anything you’d rather not share with a third party.

    Does it work with non-English text?

    Yes — the algorithm is language-agnostic; it bolds the first portion of each space-separated word. It works with any language that uses spaces between words (most European languages, Vietnamese, etc.). Languages without word spaces (Chinese, Japanese, Thai, Korean) need a tokeniser before formatting; our tool detects and warns when input lacks word boundaries.

    Related tools and guides

     

  • Test IBAN Generator: Valid Format Mod-97 [2026]

    Test IBAN Generator: Valid Format Mod-97 [2026]

    TL;DR: A test (or “fake”) IBAN generator produces strings that look like real International Bank Account Numbers — correct length per country, correct mod-97 check digit — but are not real accounts. Use them for QA-testing payment forms, generating synthetic test data, classroom examples, and validating IBAN-parsing logic. Our free test IBAN generator covers 75+ countries with the correct format per each, runs in your browser, and is honest about the only legitimate use case: testing.

    Every payment system that accepts an IBAN runs at least two checks: format (length and structure must match the country’s IBAN spec) and mod-97 (the two check digits must produce a remainder of 1 when the IBAN is interpreted as a giant integer modulo 97). A randomly-typed string fails one or both. Building or testing payment software requires inputs that pass these checks but aren’t connected to a real account — that’s where test IBANs come in.

    Our test IBAN generator produces format-correct, mod-97-valid IBANs for 75+ countries. The bank code, branch code, and account number sections are randomly filled — but with the right number of digits per country (Germany: 22 chars total, UK: 22, France: 27, Italy: 27, etc.). The resulting IBAN passes IBAN-format validators (which only check structure), but no bank in the world has that account. This guide covers when test IBANs are appropriate, the legal lines you must not cross, and the gotchas that have surprised people who thought “test IBANs” meant “free money”.

    Legitimate uses for test IBANs

    Use case OK? Why
    QA testing a payment form Yes Validates format / mod-97 logic without using real data
    Synthetic data for unit tests Yes Test fixtures need consistent, valid-shape data
    Classroom / training examples Yes Demonstrate format without using real accounts
    Mockup screenshots and slides Yes Realistic-looking placeholder data
    Filling out a real bank form No Will be flagged as suspicious; can be fraud depending on intent
    Setting up a recurring direct debit No Will fail at the bank’s account-existence check
    “Free trial” abuse No Most fraud / consumer-protection law applies; credit-card-fraud-equivalent in many jurisdictions

    The only safe rule: test IBANs are for testing your code or learning the format. They’re not a workaround for any real-world process that demands a real bank account.

    How an IBAN is structured

    An IBAN is a fixed-format string defined by ISO 13616. The structure varies per country but always follows this pattern:

    • 2 letters: ISO country code (DE, FR, GB, IT, US — but US doesn’t issue IBANs natively)
    • 2 digits: Mod-97 check digits
    • Variable digits/letters: Bank code, branch code, account number — country-specific structure

    Total length: 15 to 34 characters depending on country. Germany is 22, UK is 22, France is 27, Italy is 27, Saudi Arabia is 24. The full per-country structure is published by SWIFT and ECBS.

    The mod-97 check (and why it works)

    The check is an integrity protection against typos: take the IBAN, move the first 4 characters to the end, replace each letter with a 2-digit number (A=10, B=11, …, Z=35), then compute the resulting giant integer modulo 97. The result must be 1.

    This catches single-digit typos with high probability and most transposition errors. It doesn’t verify that the account exists — only that the format is internally consistent. So a generated IBAN passes mod-97 (we compute the check digits correctly) but a bank’s account-lookup will return “no such account”.

    How to generate test IBANs

    1. Open the test IBAN generator
    2. Pick a country (Germany default — 75+ supported)
    3. Click Generate. The IBAN appears with proper formatting (groups of 4 digits separated by spaces)
    4. Click Copy — the IBAN is copied without spaces (IBANs are stored without spaces; spaces are display-only)
    5. Generate batches of 10/100/1000 with the Bulk button for stress-testing payment forms

    Common gotchas

    • Format-valid is not account-valid. Our IBANs pass mod-97 and length checks. Banks’ real account-lookup APIs (e.g., SEPA RT1 / SCT) will reject them with “account not found” because no matching account exists. Use real test accounts from your payment provider for end-to-end testing.
    • Country-specific bank codes. Some countries (Germany, France, Italy) have published lists of valid bank codes. Our generator uses random bank codes that may or may not match a real bank — but the IBAN format remains valid. Some validators check both format AND that the bank code is in the official list.
    • SWIFT/BIC generation is separate. An IBAN by itself isn’t enough for international transfers — you also need a BIC (also called SWIFT code). Our tool generates IBAN only; for test BICs, see the SWIFT registry’s list of “00000” test prefixes.
    • Spaces don’t matter for storage. IBANs are stored as compact strings: DE89370400440532013000. Display format groups them: DE89 3704 0044 0532 0130 00. Both are equivalent.
    • Lowercase is wrong. Real IBANs use uppercase letters only. de89... is not a valid IBAN. Our generator outputs uppercase; if you typed an IBAN with lowercase, normalise before validation.
    • SEPA-extended countries. Some non-EU countries (UK post-Brexit, Switzerland, Norway) participate in SEPA and use IBAN format. Some countries (US, Canada, Australia, India, China) don’t issue IBANs at all — they use their own account number formats.

    When NOT to use a test IBAN

    For end-to-end payment testing (where money actually moves), use the test environment provided by your payment processor — Stripe, Adyen, GoCardless, Mollie all have test IBAN suites with predictable behaviour (test IBAN A succeeds, test IBAN B fails with “insufficient funds”, test IBAN C times out, etc.). For real-world use, never. For training data in machine learning models, use clearly-labeled synthetic data and document its provenance — confusing test IBANs for real ones in a model’s training set is a privacy and accuracy issue.

    Frequently asked questions

    Are these IBANs real?

    No. They’re format-valid (correct length, valid mod-97 check digits) but not connected to any real bank account. Any real bank’s account-lookup API will return “account not found”.

    Can I use these in production?

    Only as test data: in unit tests, integration tests, mock-up screenshots, classroom examples, or stress-testing your payment form. Submitting them to a real bank or merchant where you’d be expected to provide a real account is misleading and may be illegal depending on jurisdiction.

    Will my payment processor accept these for testing?

    For format-validation testing, yes — they pass the format/mod-97 check that most processors run before submitting to the bank. For end-to-end testing, no — you need test IBANs from your processor’s documented test suite that produce predictable success/failure responses.

    Why are some country IBANs longer than others?

    Country-specific banking systems use different account-number formats. France includes a 5-digit branch code; Germany uses a different 8-digit bank code; Italy includes a 1-character “CIN” check character. Total IBAN length ranges from 15 (Norway) to 34 (Saint Lucia). Each country’s structure is published by SWIFT.

    Is my data uploaded?

    No. The generator runs in your browser. Generated IBANs are computed locally — never sent to our servers.

    Can I validate an existing IBAN with this tool?

    Yes — paste an IBAN into the validator mode and the tool checks format and mod-97. It does NOT check whether the IBAN points to a real account; that requires a bank API. For format validation in production, use a library like ibantools (Node) or iban (Python).

    Related tools and guides

     

  • Image to Base64 Converter: Data URL Encoder [2026]

    Image to Base64 Converter: Data URL Encoder [2026]

    TL;DR: An image-to-Base64 converter encodes any image (PNG, JPG, WebP, SVG, GIF) as a Base64 string and wraps it in a data:image/;base64,... URL, ready to paste into HTML src, CSS url(), or JSON. Use it for inline icons under 4 KB, email templates that demand inline assets, and small SVGs that don’t justify a network request. Our free image-to-Base64 converter runs entirely in your browser — drag and drop any image, copy the result.

    A Base64 data URL inlines an image directly into HTML, CSS, or JSON. Instead of <img src="logo.png"> with a network request, you write <img src="data:image/png;base64,iVBORw0KGgo..."> and the image is part of the document. That eliminates the round-trip — useful for tiny icons in critical CSS, email templates that demand inline assets (Gmail blocks externally-hosted images by default), and JSON payloads where a separate file isn’t an option (push notifications, web push payloads, embedded widget configs).

    Our image to Base64 converter handles every common format, runs in your browser (the file never uploads), and gives you four output shapes — raw Base64, full data URL, CSS url(), and HTML <img> tag. This guide covers when inlining is the right call (often it isn’t), the size overhead (~33%), and the gotchas with caching, gzip, and font-icon migration.

    When to inline an image as Base64 — and when not to

    Use case Inline as Base64? Why
    Icon under 4 KB in critical CSS Yes Saves a request on the critical path
    HTML email template Yes (often required) Most clients block external images by default
    Large hero image (> 50 KB) No Inflates HTML, blocks parsing, no CDN caching
    Image used on every page No External file caches once, serves N times
    SVG icon set used 5+ times per page Maybe — try SVG sprite first Sprite sheets compress better than per-icon Base64
    Embed widget configuration JSON Yes JSON can’t reference external files
    Push notification icon Yes Browser push payloads are limited and need self-contained data

    The 33% size penalty

    Base64 encodes 3 raw bytes as 4 ASCII characters. That’s a 33% size overhead before any other effects. A 12 KB PNG becomes a ~16 KB Base64 string. For text-mode HTTP responses (HTML, CSS, JSON), gzip compresses the Base64 string back down — typically to within 5–8% of the original binary size. So the true overhead in a gzipped HTTP response is small.

    What gzip can’t fix: Base64-inlined assets are part of the HTML, so they block the HTML parser longer. They can’t be cached separately by the browser — every page load redownloads the whole HTML including the inline image. For an icon shown on every page, this trades a one-time round-trip for a recurring kilobyte penalty. Run the math.

    How to convert an image to Base64

    1. Open the image to Base64 converter
    2. Drop your image, click to pick a file, or paste from clipboard
    3. The converter detects the MIME type automatically (image/png, image/jpeg, image/svg+xml, etc.)
    4. Pick output format: Raw Base64, Data URL, CSS url(), or HTML <img> tag
    5. Click Copy — paste into your HTML, CSS, or JSON

    Output shapes — paste-ready for every context

    The same image produces four different output strings depending on where you’ll paste it:

    // Raw Base64
    iVBORw0KGgoAAAANSUhEUgAA...
    
    // Data URL — works in HTML src, CSS url(), JS Image()
    data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...
    
    // CSS url()
    .icon { background: url("data:image/png;base64,iVBORw...") no-repeat; }
    
    // HTML img tag
    <img src="data:image/png;base64,iVBORw0KGgo..." alt="...">

    Common gotchas

    • SVGs can be inlined more efficiently as URL-encoded SVG. Instead of data:image/svg+xml;base64,... use data:image/svg+xml;utf8,... with URL-encoded SVG markup. The result is smaller (no Base64 overhead) and gzip-compresses better. Most modern browsers support both forms.
    • Don’t inline JPEGs above ~10 KB. The Base64 string bloats your HTML by 33%, blocks the parser, and the savings from one fewer request are negligible compared to the parsing cost. Use a CDN.
    • Gmail strips inline Base64 PNGs above 4 KB in some cases. Email-client behaviour varies wildly; test with Litmus or Email on Acid before mass-mailing a campaign that depends on inline images.
    • CSP headers may block data URLs. A Content Security Policy with img-src: 'self' blocks data: URLs. Add data: to img-src if you use inline images: img-src 'self' data:;.
    • Don’t inline animated GIFs as Base64. Encoded GIF blobs are huge (often 100 KB+ for a 5-second clip), and most email clients render the first frame only anyway. Use a hosted MP4 or animated WebP for non-email contexts.
    • Build pipelines do this automatically. Webpack’s asset/inline, Vite’s ?inline import suffix, and Next.js’s next/image all auto-inline assets below a threshold. For a real codebase, configure that threshold in your bundler instead of running this tool by hand.

    When NOT to use this tool

    If your build pipeline (Webpack, Vite, Parcel, Next.js, Astro) handles inlining automatically — set the threshold in your bundler config and trust it. For batch automation in CI, write a Node script that reads the image and outputs the data URL — no browser needed. For SVG-heavy use, prefer SVG sprite sheets or inline <svg> markup over data URLs — they compress better and remain editable. Use this browser tool for one-off conversions, email templates pasted into Mailchimp/SendGrid, embed-widget config files, and learning what a data URL looks like.

    Frequently asked questions

    What’s the file size limit?

    Effectively your browser’s available memory. Conversion is fast for files up to several MB. Above 10 MB the Base64 string itself becomes unwieldy to paste. There’s no point inlining an image that large — use a CDN.

    Why does my Base64 string differ between tools?

    Same input bytes always produce the same Base64. Differences come from MIME type detection, line-break formatting (some tools insert \n every 76 characters per RFC 2045; modern tools output unbroken strings), or trailing padding. The encoded image bytes are byte-identical.

    Will inlining help my page load faster?

    For tiny critical-path images (under 4 KB, used once), yes — saves a network round-trip. For images used on multiple pages or above 10 KB, no — you bloat HTML with no caching, which is usually worse than a single fetch. Test with Lighthouse before committing.

    Does this work for SVGs?

    Yes, but a URL-encoded SVG (data:image/svg+xml;utf8,...) is usually smaller than Base64. Our converter offers both forms — pick “URL-encoded” for SVGs to save a few bytes.

    Is my image uploaded?

    No. The converter runs in your browser using the FileReader API. The image is loaded into memory and encoded locally — it never leaves your device. You can verify in the Network tab: dropping a file produces zero outbound requests.

    Can I decode Base64 back to an image?

    Yes — paste a data URL into the converter and toggle “Decode mode”. The original image is reconstructed and offered as a download. Useful for inspecting an inlined asset you want to extract from a page.

    Related tools and guides

     

  • React Native Shadow Generator: iOS + Android [2026]

    React Native Shadow Generator: iOS + Android [2026]

    TL;DR: React Native handles shadows with two completely different APIs depending on platform. iOS uses four properties: shadowColor, shadowOffset, shadowOpacity, shadowRadius. Android uses one — elevation — which renders a Material-Design-style shadow whose appearance you can’t fully control. Our free React Native shadow generator shows both side by side, lets you tune iOS to match an Android elevation visually, and outputs a copy-paste StyleSheet block including the cross-platform Platform.OS guard.

    Shadows on a React Native card sound like one feature; they’re actually two implementations with no overlap. iOS reads the four shadow* props that map closely to Apple’s CALayer shadow API. Android ignores all four and reads elevation only — a 0–24 numeric value that the Material framework converts into a system-rendered shadow. Set both: iOS uses its props, Android uses elevation. Set only iOS-style props: Android is shadowless. Set only elevation: iOS is shadowless. Pretty much every “why does my shadow not show up?” Stack Overflow question is one of these three.

    Our React Native shadow generator renders both platforms side-by-side with a live preview that approximates each platform’s rendering. You set the iOS values, see the Android equivalent under our preset mapping, and copy a single StyleSheet block that works on both. This guide covers the prop semantics, the iOS-vs-Android visual mismatches, and the gotchas with backgroundColor, borderRadius, and overflow.

    iOS shadow props vs Android elevation

    Property Platform Type Default
    shadowColor iOS only colour 'black'
    shadowOffset iOS only { width, height } { width: 0, height: 0 }
    shadowOpacity iOS only number 0–1 0 (invisible)
    shadowRadius iOS only number (px) 3
    elevation Android only number (0–24) 0

    Mapping iOS values to Android elevation

    Material Design’s elevation system is a fixed scale: 1 = subtle, 2 = card, 4 = button, 6 = dropdown, 8 = floating action button, 16 = navigation drawer, 24 = highest layer. There’s no Android API to fully customise the shadow — you pick a number and Android renders the matching Material shadow. Approximate iOS-to-Android mapping:

    • iOS subtle (offset 0/2, opacity 0.1, radius 3) ≈ elevation: 2
    • iOS soft card (offset 0/4, opacity 0.15, radius 6) ≈ elevation: 4
    • iOS prominent (offset 0/6, opacity 0.2, radius 10) ≈ elevation: 8
    • iOS dramatic (offset 0/12, opacity 0.3, radius 16) ≈ elevation: 16

    Pixel-perfect parity isn’t possible — the platforms render shadows with different algorithms. Aim for visual equivalence at the design-system level: a “card” looks like a card on both platforms.

    How to generate a React Native shadow

    1. Open the React Native shadow generator
    2. Adjust the four iOS sliders: shadowColor, shadowOffset, shadowOpacity, shadowRadius
    3. The Android elevation slider tracks automatically (or override manually)
    4. Watch the side-by-side preview — iOS on the left, Android approximation on the right
    5. Click Copy StyleSheet for a complete cross-platform block

    Cross-platform StyleSheet pattern

    The standard React Native shadow shim looks like this:

    import { StyleSheet, Platform } from "react-native";
    
    const styles = StyleSheet.create({
      card: {
        backgroundColor: "white",
        borderRadius: 12,
        padding: 16,
        ...Platform.select({
          ios: {
            shadowColor: "#000",
            shadowOffset: { width: 0, height: 4 },
            shadowOpacity: 0.15,
            shadowRadius: 8,
          },
          android: {
            elevation: 4,
          },
        }),
      },
    });

    Note backgroundColor is required on Android for elevation to render — without it, Android won’t draw the shadow even though the prop is set. iOS doesn’t have this requirement.

    Common gotchas

    • Android elevation requires backgroundColor. A transparent or undefined background makes Android skip the shadow entirely. Always set a background colour for elevation to render.
    • iOS shadow doesn’t follow rounded corners by default. Set shadowPath via the older shadowOffset shape, or use the react-native-svg-shadow library if you need precision. Most cases are fine without.
    • Don’t use both elevation and iOS props on Android. elevation alone produces the Material shadow; adding iOS props doesn’t help and may break expected layouts in some RN versions.
    • shadowOpacity defaults to 0. If you set everything else but skip shadowOpacity, your iOS card has no shadow. The most common “shadow doesn’t show” cause on iOS.
    • overflow: hidden clips shadows on iOS. A card with overflow: 'hidden' (e.g., to clip an image to rounded corners) hides its own shadow. Wrap the clipped element in a parent that has the shadow, then put the clipped child inside.
    • Color names differ. iOS accepts CSS colour names; Android accepts standard names too but some hex strings render differently. Stick to hex ('#000') for cross-platform consistency.
    • RN 0.71+ supports new architecture. The new (Fabric/TurboModules) renderer respects shadow props more consistently across both platforms. Older versions (RN <0.65) may need third-party libraries like react-native-shadow-2 for visual parity.

    When NOT to use this tool

    For complex shadows (multiple stacked shadows, inner shadows, coloured shadows beyond simple offsets), use a third-party library: react-native-shadow-2 renders SVG-based shadows that look identical on both platforms. For text shadows, use the dedicated textShadowColor, textShadowOffset, textShadowRadius props (different from view shadows). For Web React Native (RN Web), neither shadow API works — use CSS box-shadow via style.shadowOffset = ... with platform check or a CSS-in-JS library.

    Frequently asked questions

    Why doesn’t my shadow show on Android?

    Three usual causes: (1) you set iOS props but no elevation — Android ignores iOS props; (2) you set elevation but the parent has no backgroundColor — Android needs an opaque background to render the shadow; (3) overflow: 'hidden' on the parent clips the shadow. Add elevation, set backgroundColor, remove overflow: hidden.

    Why doesn’t my shadow show on iOS?

    Almost always shadowOpacity is 0 (the default). Set it to 0.1–0.3. Other causes: shadowColor is transparent, parent has overflow: 'hidden', or the view has no backgroundColor (transparent views can’t cast shadows on iOS either, though it’s less strict than Android).

    Can I have a coloured shadow?

    iOS yes — set shadowColor: '#FF0000'. Android no — elevation always renders the system Material shadow which is roughly black with system-controlled opacity. For coloured shadows on Android, use react-native-shadow-2 or render a manual SVG shadow.

    Does this work on Expo and bare React Native?

    Yes. Both shadow APIs are part of core React Native; they work identically in Expo and bare projects. No native modules required.

    What’s the difference between elevation and zIndex?

    elevation controls visual shadow depth on Android. zIndex controls render order (which view appears in front). They’re independent — a high-elevation card with low zIndex still appears behind other views. Set both together when you want an elevated card to also be on top.

    Is my data uploaded?

    No. The generator runs in your browser. The shadow values, preview, and exported StyleSheet stay on your device.

    Related tools and guides

     

  • Text to Handwriting Converter Online [2026]

    Text to Handwriting Converter Online [2026]

    TL;DR: A text-to-handwriting converter renders typed input as natural-looking handwriting on a paper background — ruled, blank, or grid. Used for journaling aesthetics, faux-handwritten letters, classroom worksheets, lecture-note mockups, and legitimate accessibility tasks (reading-disability research). Our free text-to-handwriting tool ships 12 handwriting fonts, ink colour control, paper styles, jitter (natural variation), PDF export, and a watermark to discourage misuse. Browser-only — your text never leaves your device.

    The handwritten-look aesthetic shows up everywhere — Pinterest journaling boards, Notion bullet-journal templates, Etsy printable worksheets, social-media planner mockups. Designers used to fake it by typing in a “handwriting” font in Photoshop, but native handwriting fonts placed on a digital page give themselves away: identical letters every time, perfectly aligned baselines, no ink-flow variation. Real handwriting jitters, varies pressure, drifts off the line.

    Our text to handwriting converter renders typed input on canvas with three sources of natural variation: per-letter rotation (each character tilts ±2° randomly), baseline jitter (letters drift up/down a few pixels), and ink density variation (some characters render darker than others, mimicking varying pen pressure). Add ruled-paper backgrounds, control ink colour (blue, black, red, custom), and export PNG, JPG, or PDF. This guide explains how the renderer works, when handwritten output is the right choice, and the legitimate-vs-deceptive line you mustn’t cross.

    Common use cases — and the legal line

    Use case Legitimate? Notes
    Pinterest journal mockup Yes Aesthetic content, no deception
    Faux-letter for fiction / film Yes Artistic work — clearly creative
    Tutorial / classroom example Yes Educational use, attributed
    Reading-disability research Yes Test handwriting recognition / OCR
    Skipping a handwritten assignment No Academic dishonesty in most schools
    Forging a handwritten document No Forgery — illegal in every jurisdiction
    Faking a “handwritten” doctor’s note No Document fraud, can be criminal

    The output is a digital image, not real handwriting. It will not pass a forensic handwriting-comparison test. Use it for legitimate creative work; never to deceive someone into thinking the text was actually written by hand.

    How natural variation is generated

    Real handwriting has three sources of variation our renderer reproduces:

    • Per-letter rotation: each character tilts ±0.5° to ±3° depending on the jitter slider. Without rotation, letters look stamped-on; with too much, letters look drunk.
    • Baseline drift: the y-position of each character varies ±2px. Real handwriting drifts above and below the imaginary baseline because the writer’s hand moves.
    • Pressure variation (ink darkness): each character renders at 90–100% opacity randomly. Real pen pressure produces lines of varying darkness — the renderer simulates this with per-character alpha.

    The result: same input rendered twice produces two different-looking outputs. The same letter (e.g., ‘a’) appearing five times in a sentence rotates and jitters differently each time. Click “Re-render” to shuffle the random seed and get a new variation.

    How to convert text to handwriting

    1. Open the text to handwriting converter
    2. Type or paste your text
    3. Pick a handwriting font from the 12-font library (Caveat, Patrick Hand, Indie Flower, Kalam, Shadows Into Light, etc.)
    4. Choose paper style: ruled, grid, blank, dotted, or yellow legal pad
    5. Set ink colour, jitter level, and font size
    6. Click Re-render for variation; click Export for PNG, JPG, or PDF

    Handwriting fonts and what each is for

    • Caveat: casual modern script, most popular default. Reads like a marker-on-paper note.
    • Patrick Hand: narrower, bullet-journal aesthetic.
    • Indie Flower: rounded, friendly, looks like middle-school print handwriting.
    • Kalam: Indic-script-friendly, cleaner ink lines.
    • Shadows Into Light: casual, slightly slanted, reads like quick notes.
    • Homemade Apple: messy, deliberately imperfect.
    • Sacramento: formal cursive — for “thank you” cards and wedding invitations.
    • Permanent Marker: bold marker style — for poster mockups.
    • Just Another Hand: condensed letters, fast-handwriting feel.
    • 3 more for variety.

    Common gotchas

    • Real handwriting recognition isn’t fooled. An OCR system or a forensic handwriting analyst will identify generated handwriting instantly — letter-frequency analysis, consistent stroke patterns, and font-rendering artefacts give it away. Don’t expect this to fool any system that examines handwriting.
    • Long passages take a while. Rendering each character individually with per-character rotation is slow. A single page of text (~250 words) takes 1–3 seconds; a full essay (1,500+ words) can take 10–20 seconds. Break long content into pages and export per-page PDFs.
    • Cursive fonts can be hard to read. Sacramento and similar formal-cursive fonts look elegant but reduce reading speed by 30%+ for typical readers. Use casual print-style fonts (Caveat, Patrick Hand) for readability; cursive for aesthetic-only mockups.
    • Paper texture is procedural. The “ruled paper” background isn’t a high-res scan — it’s drawn at render time. Export at higher resolution (2× or 3×) for print; lower resolutions make the texture look obviously digital.
    • Ink colour interacts with paper. Black ink on yellow legal-pad paper looks fine; light blue ink on white paper looks washed out. Match ink colour to paper for legible output.
    • Special characters render inconsistently. Some handwriting fonts don’t include glyphs for em-dashes, smart quotes, or accented characters — they fall back to a default font, breaking the handwritten illusion. Stick to ASCII for the most consistent look.

    When NOT to use this tool

    For real handwriting practice (improving your own handwriting), use a handwriting workbook — a generator can’t help. For accessibility tools that need true handwritten outputs, use an iPad-with-Apple-Pencil workflow. For commercial use of the output (selling printables on Etsy, using in client deliverables), check the licensing of each handwriting font — most Google Fonts are SIL Open Font Licence (free for commercial), but custom fonts may have restrictions. For document forgery or any use that misleads someone — don’t use this tool, full stop. The output is intended for legitimate creative and educational work.

    Frequently asked questions

    Will this fool a teacher / professor?

    Probably not, and don’t try — it’s academic dishonesty. The output is digital with consistent letter shapes that an experienced grader spots quickly. Use the tool for creative projects, mockups, and presentations — not to skip handwritten assignments.

    Can I use my own handwriting font?

    Yes — upload a custom font file (TTF or WOFF). Some users digitise their own handwriting using services like Calligraphr (free for one font) and upload the result for genuinely personal handwriting output.

    What’s the difference between a handwriting font and this tool?

    A static font renders every ‘a’ identically — gives away that it’s typed. This tool adds per-character rotation, baseline jitter, and pressure variation, so the same letter looks different each time it appears. Same starting font; much more natural-looking output.

    Can I export at high resolution for print?

    Yes — pick 2× or 3× resolution before export. PDF output is vector for the paper rules but raster for the rendered text (at 300 DPI by default). For poster-size print, export at 4× and downscale slightly in your print software.

    Is my text uploaded?

    No. The renderer uses canvas in your browser. Your text, the font choice, and the exported image all stay on your device — never sent to our servers.

    Can I batch-render many pages?

    Yes — paste multi-page text and the tool paginates automatically (using a page-break marker or after N lines). Export produces a multi-page PDF or a ZIP of PNG files, one per page.

    Related tools and guides

     

  • SHA-384 Hash Generator: 384-bit Digest [2026]

    SHA-384 Hash Generator: 384-bit Digest [2026]

    TL;DR: SHA-384 produces a 384-bit (48-byte / 96 hex character) hash. It’s SHA-512 with a different starting state and a truncated 384-bit output. 192-bit collision resistance — overkill for most uses, but mandated in NSA Suite B / CNSA-compliant cryptography, TLS 1.3 cipher suites, and US government high-assurance systems. Faster than SHA-256 on 64-bit hardware. Our free SHA-384 hash generator uses the browser’s native WebCrypto API.

    SHA-384 occupies the same family-niche as SHA-224: a SHA-2 hash with truncated output for compliance reasons. Where SHA-224 is the truncated SHA-256 for legacy 112-bit security, SHA-384 is the truncated SHA-512 for high-security applications that don’t need a full 512-bit hash but want more than SHA-256’s 128-bit collision resistance. Real-world use is concentrated in government and high-assurance crypto:

    • TLS 1.3: the TLS_AES_256_GCM_SHA384 cipher suite uses SHA-384 in HKDF for key derivation.
    • NSA Suite B / CNSA: the US National Security Agency’s commercial cryptography spec requires SHA-384 (or SHA-512) for top-secret data classifications.
    • PKI / X.509 certificates: ECDSA signatures over P-384 curves naturally pair with SHA-384.
    • Long-lived archive integrity: the extra 64 bits over SHA-256 add comfortable security margin.

    Our SHA-384 hash generator uses the browser’s native SubtleCrypto.digest('SHA-384', ...) API — same code path that handles HTTPS certificate verification — and runs entirely on your device. This guide covers when SHA-384 is the right pick, the performance characteristics, and the gotchas with truncation.

    SHA-2 family at a glance

    Algorithm Output Collision security Performance
    SHA-224 224 bits 112-bit Same as SHA-256
    SHA-256 256 bits 128-bit Slower on 64-bit
    SHA-384 384 bits 192-bit Same as SHA-512 (faster on 64-bit)
    SHA-512 512 bits 256-bit ~30% faster than SHA-256 on 64-bit

    Why SHA-384 is faster than SHA-256 on modern hardware

    SHA-384 uses the SHA-512 compression function — operating on 64-bit words and 1024-bit blocks — and just truncates the output. On a 64-bit CPU each word fits in a single register. SHA-256, despite producing a smaller output, runs on 32-bit words requiring more operations per byte hashed.

    Benchmark on a 2024 laptop:

    • SHA-256: ~600 MB/s
    • SHA-384: ~880 MB/s (≈47% faster)
    • SHA-512: ~880 MB/s (same internal work as SHA-384)

    Counter-intuitively, picking SHA-384 over SHA-256 for new code can mean both more security and better performance on 64-bit hardware. The trade-off is 32 extra hex characters in output.

    When you’d actually use SHA-384

    • NSA Suite B / CNSA-compliant systems. US government top-secret classification mandates SHA-384 minimum. If you’re in defence / intelligence contracting, this is the spec.
    • TLS 1.3 with AES-256-GCM. The TLS_AES_256_GCM_SHA384 cipher suite is one of TLS 1.3’s three default suites. Browsers negotiate it automatically; you don’t pick it manually.
    • PKI signatures with P-384 curves. ECDSA on the NIST P-384 curve naturally pairs with SHA-384 for matching security level.
    • Compliance frameworks specifying 192-bit security. Some financial regulations (PCI DSS in select profiles), ANSSI guidelines, BSI specs.
    • Long-lived archive integrity. The 64 extra bits over SHA-256 add margin for hashes verified decades from now.

    For most everyday checksums and integrity verification, SHA-256 is the right default — universally supported, established, well-tested. SHA-384 is for compliance-driven cases.

    How to compute SHA-384 in your browser

    1. Open the SHA-384 generator
    2. Type or paste text — the digest appears live
    3. Or drop a file — bytes streamed through WebCrypto, no upload
    4. Click Copy. Toggle UPPERCASE / lowercase output
    5. For HMAC-SHA-384, click HMAC mode and paste a key

    Common gotchas

    • SHA-384 is not truncated SHA-512. Like SHA-224 / SHA-256, the truncated variants use different initial hash values. sha512(x).substring(0, 96) !== sha384(x). Always compute SHA-384 specifically.
    • UTF-8 encoding before hashing. Same input, different encoding, different hash. Use UTF-8.
    • Don’t use for password storage. SHA-384 is too fast — use bcrypt / scrypt / argon2id for passwords.
    • HMAC-SHA-384 has different block size. SHA-384 / SHA-512 use 1024-bit (128-byte) blocks; SHA-256 uses 512-bit (64-byte) blocks. HMAC implementations need to use the matching block size — common bug in hand-rolled HMAC code.
    • Length-extension affects bare SHA-384 too. Use HMAC, not sha384(secret || data).
    • Some old systems don’t ship SHA-384. Older PHP, older Java, very old C libraries may lack SHA-384. Check support before specifying.

    When NOT to use SHA-384

    For everyday integrity checks (file checksums, deterministic IDs, message integrity in non-compliance contexts), SHA-256 is the right default — universally supported, smaller output, well-known. For password storage: use bcrypt / scrypt / argon2id; never plain SHA-384. For the longest possible security margin in archive integrity: SHA-512 (full output, same algorithm internally). For TLS 1.3 cipher suite selection: don’t manually pick — let the protocol negotiate. Use SHA-384 specifically when a spec mandates it.

    Frequently asked questions

    Is SHA-384 stronger than SHA-256?

    Yes — 192-bit collision resistance vs SHA-256’s 128-bit. Both are far beyond what’s brute-forceable today; SHA-384 matters when compliance frameworks demand the higher security level (NSA Suite B / CNSA, certain financial standards).

    Why is SHA-384 sometimes faster than SHA-256?

    SHA-384 uses the SHA-512 compression function, which operates on 64-bit words. On 64-bit CPUs each word fits a single register, giving SHA-384 / SHA-512 a 30–50% throughput advantage over SHA-256. On 32-bit hardware (rare in 2026) the trade reverses.

    Is SHA-384 just truncated SHA-512?

    Same compression function, different initial hash values (IVs). Truncating SHA-512 to 96 hex characters does NOT produce the SHA-384 hash. Always compute SHA-384 specifically.

    Should I use SHA-384 or SHA-512 for new code?

    Without a specific compliance reason, SHA-256 is the default. If you need 192-bit collision resistance, SHA-384. If you need 256-bit, SHA-512. Don’t pick SHA-384 over SHA-512 for marginal output-size reasons — both run the same internal work.

    Is my input uploaded?

    No. The generator runs the browser’s native SubtleCrypto.digest API. Text and files are processed locally — never sent to our servers.

    What’s HMAC-SHA-384 and when is it used?

    HMAC-SHA-384 is a keyed hash combining a secret key with the SHA-384 algorithm. Used for message authentication where you need to verify both data integrity and that the sender knew the key. Common in JWT signatures (JOSE algorithm HS384) and AWS Signature Version 4 for high-assurance API calls.

    Related tools and guides

     

  • Code to Image Converter: Beautiful Code Screenshots [2026]

    Code to Image Converter: Beautiful Code Screenshots [2026]

    TL;DR: A code to image converter takes source code and renders it as a beautiful syntax-highlighted screenshot — perfect for sharing on Twitter/X, LinkedIn, blog posts, and tutorial slides. Our free code to image converter supports 100+ languages, multiple themes (Dracula, GitHub Light, Tokyo Night, etc.), window-chrome styling, and exports a high-resolution PNG. Browser-only, no upload.

    Plain code in a tweet looks awful. Twitter strips formatting, mobile viewers can’t read it, and you can’t paste a 30-line function as text without it becoming a mess. Code-to-image converters solve this — render your snippet with proper syntax highlighting, a stylised window chrome, and export as PNG. The result looks like a screenshot from your editor but is actually a fresh render at any resolution. Carbon (carbon.now.sh) popularised the format around 2017; the workflow is now standard for developer-influencer Twitter, conference slides, and tutorial blog posts.

    Our code to image converter supports 100+ programming languages via highlight.js, multiple popular themes, window controls (the three macOS dots), and adjustable padding/font size. Everything renders client-side; your code never transmits. This guide covers the language detection, theme choices that read well on social media, and the typography settings that produce clean exports.

    Why developer Twitter loves code screenshots

    • Visual punch in feeds. A code screenshot stops the scroll where plain text doesn’t. Tweets with code images get 4-6× the engagement of equivalent text-only tweets.
    • Twitter’s text rendering destroys formatting. Indentation collapses, monospaced characters render in proportional fonts, lines wrap unpredictably. An image preserves exactly what you wrote.
    • Multi-language demonstration. Showing the “before vs after” of a refactor, or comparing TypeScript vs JavaScript, requires consistent visual treatment that only screenshots provide.
    • Slides and tutorial content. Conference talks and YouTube tutorials need code that reads on a projected screen from 30 feet away. Screenshots at 4K resolution scale better than IDE captures.

    How to use the browser code-to-image converter

    1. Open the code to image converter
    2. Paste or type your code into the editor
    3. Pick a language (auto-detected for most common languages)
    4. Pick a theme — Dracula, Tokyo Night, GitHub Light, Atom One Dark, Monokai, and more
    5. Adjust padding, font size, line numbers, window chrome (macOS dots, title bar, none)
    6. Set background colour or gradient
    7. Click Export PNG. The result downloads at 2× retina resolution

    All rendering happens in your browser via canvas. Your code is never uploaded.

    Themes that read well on social media

    • Dracula: dark background with vibrant pink/purple/green syntax. Most popular on developer Twitter.
    • Tokyo Night: deep navy with muted neon highlights. Reads well in dense feeds.
    • GitHub Light: the official GitHub theme, conservative, professional. Good for enterprise/business contexts.
    • Atom One Dark: dark with balanced colours. Good for screenshots that include both code and surrounding light UI.
    • Monokai: classic dark theme, slightly retro feel. Works for teaching content.

    Avoid pure black backgrounds. They look harsh and produce posterised compression artefacts on Twitter’s recompressed images. Dark grey (#1a1b26 or similar) compresses cleaner.

    Typography that exports cleanly

    • Font size 14-18 px for the editor view. The export at 2× will be 28-36 px effective, which reads well on retina displays and projector screens.
    • Use a programming-friendly font. JetBrains Mono, Fira Code, Cascadia Code, IBM Plex Mono — designed for code with clear letterforms. Avoid system monospace; it varies by platform.
    • Line height 1.5-1.6. Tighter is dense; looser is loose. 1.5 reads well across most themes.
    • Width 60-80 characters. Match the visual rhythm of well-formatted code editors. Longer lines truncate visually on social media.

    Common mistakes

    • Wrong language selection. If TypeScript is highlighted as JavaScript, you lose type-syntax colouring. Auto-detect helps but verify before exporting.
    • Tiny font for “show more code”. Cramming 100 lines into one image produces unreadable thumbnails. Better to show 15-20 lines crisply than 100 illegibly.
    • Forgetting to crop padding. Default padding may be excessive; crop tight for use in slides where screen space is limited.
    • Ignoring contrast for accessibility. Some popular themes have low syntax-vs-background contrast. Test the export at typical mobile viewing distance.

    Frequently asked questions

    What languages does the converter support?

    100+ via highlight.js — every major language (JavaScript, TypeScript, Python, Java, Go, Rust, C/C++, C#, PHP, Ruby, Swift, Kotlin), markup (HTML, JSX, TSX, Markdown), data (JSON, YAML, TOML, XML), shell (Bash, Zsh, PowerShell), database (SQL), and many less-common languages.

    Can I share the result directly to Twitter?

    The exported PNG copies to your clipboard or downloads. Paste into your tweet composer, attach the file, or drag-drop. The image is the right aspect ratio for Twitter’s preview without further cropping.

    Is my code uploaded when I use the tool?

    No. The browser highlights your code locally via highlight.js and renders the image on canvas. Your code, the highlighted output, and the PNG export all stay on your device.

    Can I add a watermark or branding?

    Custom watermarks aren’t built in, but the exported PNG is clean — no simpletool.io branding. Add your own watermark in your design tool after export, or use the URL/handle as a small text overlay in the window chrome.

    What’s the resolution of the export?

    2× retina based on the editor view. A 600×400 editor exports at 1200×800 PNG. Sharp on retina displays and good for projector use.

    Why does my code look different in the export than in my IDE?

    IDE colour themes vary — VS Code’s “One Dark” has subtle differences from Atom’s “One Dark”. Pick the closest theme in the converter, or accept slight differences. The semantic colouring (keywords, strings, comments) is consistent; exact hex values differ.

    Related tools and guides

     

  • JavaScript Minifier: Shrink JS 60–70% in Browser [2026]

    JavaScript Minifier: Shrink JS 60–70% in Browser [2026]

    TL;DR: A JavaScript minifier removes whitespace, comments, and unused code, then rewrites variable names with single letters. Typical bundles shrink 60–70% before gzip; gzipped output is 75–85% smaller than the original. Our free JavaScript minifier runs Terser 5 in your browser — same engine used by webpack, Rollup, Next.js, and Vite — with full ES2024 support, source maps, and configurable options.

    Minifying JavaScript is the cheapest performance win in a web project. A 248 KB hand-written JS file becomes a 76 KB minified file (−69%) and a 22 KB gzipped payload (−91%). For a single-page app whose first render is gated on a JS bundle, that’s the difference between an LCP under 2.5 seconds and a sluggish first paint. Build tools like webpack, Vite, and Next.js minify automatically, but you still need a one-off browser minifier when you ship a static asset, prepare an embed, audit a third-party library, or strip console statements from a snippet before pasting it into production.

    Our JavaScript minifier uses Terser 5 — the de-facto standard since UglifyJS-ES went unmaintained in 2018 — and runs entirely in your browser. ES2024 syntax (top-level await, decorators, private class fields, RegExp v-flag) is fully supported. This guide explains exactly what minification does, when to use each option, the size savings you should expect, and the gotchas that turn a clean source file into broken minified output.

    What minification actually does (and doesn’t)

    Transformation Savings Risk?
    Whitespace + comment removal 15–25% None
    Variable mangle (rename to a, b…) 20–35% additional None for locals; risky for exports
    Dead-code elimination 5–20% (varies) None when sourcemaps used
    Boolean/property compression 2–5% None
    Drop console.* statements 1–3% Loses debug visibility
    Property mangle (obj.fooobj.a) 10–20% additional High — breaks JSON/runtime keys

    The default Terser preset gives you the first 5 transforms safely. Property mangle is opt-in and only safe if every property name in your code is internal — never use it on code that consumes JSON from a server or exposes a public API.

    Realistic file-size expectations

    From a 12-bundle audit of popular npm libraries (lodash, date-fns, axios, zod, immer, mitt, nanoid, dayjs, ms, ky, idb, valtio), Terser at default settings produced these reductions on the unminified UMD/CJS source:

    • Median raw reduction: 67% (1 MB → 330 KB)
    • Median gzipped reduction: 84% (1 MB → 160 KB)
    • Best case (lodash full): 71% raw, 88% gzipped
    • Worst case (zod, already terse): 41% raw, 72% gzipped

    Roughly: minification halves the size; minification + gzip removes 80–90%. If a file is already minified (filename ending in .min.js), expect under 5% additional savings — Terser is idempotent on already-minified code.

    How to minify JavaScript in your browser

    1. Open the JavaScript minifier
    2. Paste your code or drop in a .js file (up to several MB)
    3. Pick options: Mangle, Compress, Drop console, Source map
    4. Click Minify — output appears with before/after sizes
    5. Click Copy or Download .min.js (and .map if source maps are enabled)

    Source maps: why you should always generate one

    A source map (.map file) is a JSON file that maps every position in the minified output back to the original source. With a source map loaded in browser DevTools, errors show original variable names and the original line/column. Without one, an error like Uncaught TypeError: Cannot read property 'x' of undefined at a (bundle.min.js:1:24871) is unactionable.

    Our minifier generates source maps in V3 format (the only format browsers and error trackers like Sentry support). Two options: external (separate .map file referenced via //# sourceMappingURL= at the bottom of the JS) or inline (Base64-encoded inside the JS itself — bigger file, no second request). Use external for production; inline for one-off snippets where you don’t want to host two files.

    Common gotchas

    • Don’t mangle property names by default. The Terser mangle.properties option renames obj.userName to obj.a. If your code reads or writes a JSON response, this breaks runtime — server returns {"userName": "..."} but your minified code looks for obj.a.
    • Always produce sourcemaps for production. Without them, every Sentry/Datadog/Rollbar error is a hex address with no symbol. Upload .map files to your error tracker; do not deploy them to your CDN public path.
    • Drop console for production only. The drop_console option strips all console.* statements — including console.error in catch blocks. If you rely on those for production diagnostics, use pure_funcs: ['console.log', 'console.debug'] to keep error and warn.
    • Comments matter for licences. By default Terser drops every comment. Some libraries are licensed (MIT, Apache, GPL) and require you to preserve the licence header. Use the /* @preserve */ or /*! ... */ annotation, or set Terser’s format.comments to 'some'.
    • Top-level await disables some optimisations. Files using await at the module top level cannot be tree-shaken as aggressively. Bundle splitters often produce a separate chunk for these modules.
    • Don’t minify twice. Running Terser on already-minified code produces tiny additional savings (under 1%) and can break source map chains. Only minify once, at the build-final stage.

    When NOT to use a browser minifier

    If you have a build pipeline (webpack, Vite, esbuild, Next.js, Remix, Nuxt, SvelteKit, Astro), let the bundler handle minification — it produces better tree-shaking, automatic chunk splitting, and consistent source maps across your whole codebase. Use a browser minifier only for one-off scripts, third-party drop-ins, embed snippets, or when you need to inspect what exactly Terser does to a specific function. For Node.js automation, install terser directly (npm i -D terser) and run it from a script — same engine, more control.

    Frequently asked questions

    Is Terser safe to use on modern ES2024 syntax?

    Yes. Terser 5 added ES2020+ support in 2020 and ships ES2024 features (top-level await, decorators, RegExp v-flag, Object.hasOwn, Array grouping). The minifier reads the source as the latest ECMA spec by default. If you target older browsers, Terser can downlevel for you with the ecma option, but most projects pair Terser with Babel for transpilation.

    How much does gzip add on top of minification?

    About another 50%. A 76 KB minified file gzips to roughly 22 KB. Brotli (used by most CDNs since 2019) shrinks another 8–15% beyond gzip. Always serve .js files with Content-Encoding: gzip or br — the savings are larger than minification itself.

    Will minification change how my code runs?

    Functionally, no — Terser is conservative by default. Two edge cases to watch: Function.prototype.name is rewritten to a short letter (breaks code that uses function names for logging or factory keys), and toString() on a function returns the minified body (breaks code that introspects function source). Both are rare; document them if your code relies on them.

    Can I unminify or beautify minified code?

    Partially. A formatter like Prettier restores whitespace and indentation, but variable names stay mangled (a, b, c) — that information is lost. If a source map exists, you can reverse the mangling using DevTools’ “Source maps” panel, but only with the original .map file.

    Is my code uploaded?

    No. The minifier runs Terser entirely in your browser via WebAssembly. Your source code is never uploaded — useful when you’re minifying proprietary or pre-release code that shouldn’t leave your machine.

    What’s the size limit for the input?

    Effectively your browser’s available memory. Terser has minified single files of 10+ MB in our testing on a laptop. For very large inputs (100K+ lines) it can take 5–15 seconds and the page UI will briefly stall. The output streams as soon as parsing completes.

    Related tools and guides

     

  • JWT Decoder Online: Inspect Tokens in Browser [2026]

    JWT Decoder Online: Inspect Tokens in Browser [2026]

    TL;DR: A JWT decoder splits a JSON Web Token into its three Base64-URL-encoded parts — header, payload, signature — and renders them as readable JSON. Use it to inspect what an API token actually claims (user ID, expiry, scopes), debug auth issues, or build new tokens. Our free JWT encoder/decoder handles HS256 and RS256, verifies signatures locally, and never transmits the token.

    JWT (JSON Web Token) is the auth standard for modern APIs. Every OAuth flow, every Auth0 / Cognito / Firebase Auth integration, every internal microservice that needs to pass identity around — all of them use JWTs. The token looks like gibberish: eyJhbGciOi…. Decoded, it’s three small JSON objects that say “this user, signed by this issuer, valid until this time”. Decoding is non-secret — anyone with the token can read its contents. Verifying the signature requires the secret. Both operations are routine for backend developers and frequently need a quick lookup tool.

    Our JWT encoder/decoder takes any JWT string and renders the header + payload as pretty-printed JSON. Optionally paste the secret to verify the signature, or build a fresh token from custom JSON. Everything runs in your browser via the Web Crypto API; the token and secret never transmit. This guide explains JWT structure, the differences between HS256 and RS256, and the security gotchas that have produced real-world authentication failures.

    JWT structure — three Base64-URL parts joined by dots

    eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkphbmUiLCJpYXQiOjE2NjcwMDAwMDB9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
       ↑ header                ↑ payload                                                        ↑ signature
       {"alg":"HS256"}          {"sub":"1234567890","name":"Jane","iat":1667000000}
    • Header: the algorithm used (HS256, RS256, etc.) and the token type. Always JSON.
    • Payload: the claims — user ID, scopes, issued-at, expiry, custom application data. The actual identity assertion.
    • Signature: a cryptographic signature of header.payload using either a shared secret (HS256) or the issuer’s private key (RS256). This is what makes the token tamper-evident.

    Standard claims every JWT might include

    Claim Meaning
    sub Subject — usually the user ID
    iss Issuer — who created the token
    aud Audience — who the token is for
    exp Expiry — Unix timestamp after which the token is invalid
    iat Issued-at — Unix timestamp of token creation
    nbf Not-before — token isn’t valid until this time
    jti JWT ID — unique identifier for revocation lists

    Beyond the standard claims, applications add custom claims (scopes, roles, email, anything else). Decoding a token reveals all claims; this is why JWTs should never carry secrets.

    HS256 vs RS256 — choosing the right algorithm

    • HS256 (HMAC-SHA-256): uses a shared secret known to both signer and verifier. Simpler, faster, smaller signatures. Right when one service signs and the same service verifies. Wrong when verification needs to happen on multiple machines without sharing a secret.
    • RS256 (RSA + SHA-256): uses asymmetric crypto. Issuer holds a private key; verifiers use the public key. Right for any “sign here, verify everywhere” pattern (Auth0, Firebase Auth, Google OAuth all use RS256). The public key can be distributed freely.
    • ES256 (ECDSA): elliptic-curve variant of RS256. Smaller signatures, faster signing, equivalent security. Increasingly common in IoT and mobile contexts.

    The rule of thumb: HS256 for monolithic apps where one service signs and verifies. RS256 for anything multi-service, distributed, or where third parties need to verify.

    How to use the browser JWT decoder

    1. Open the JWT encoder/decoder
    2. Paste your JWT into the input. Header and payload appear as pretty-printed JSON instantly
    3. Optional: paste the signing secret (HS256) or public key (RS256) to verify the signature. Result shows ✓ valid or ✗ invalid
    4. Switch to Encode mode to build a new token from custom JSON
    5. Copy any decoded part with the per-section copy buttons

    Real-world JWT security mistakes

    • The “alg: none” attack. Some libraries trust the algorithm specified in the header. Setting it to “none” tells the library to skip signature verification. Always specify the expected algorithm at verification time.
    • Confusing HS256 with RS256. If a service expects RS256 but accepts HS256 with the public key as the secret, attackers can forge tokens. Always pin the algorithm.
    • Leaving secrets in JWT payloads. JWTs are encoded, not encrypted. Anyone with the token reads the payload. Never put passwords, API keys, or PII in claims.
    • Long expiry times. A 90-day JWT can’t be revoked without maintaining a denylist. Keep exp short (15-60 minutes) and use refresh tokens for sustained sessions.
    • Using HS256 with weak secrets. A 16-byte secret is brute-forceable. Use 32+ bytes (256 bits) of randomness for HS256 secrets.

    Decoding JWT in code

    // Node.js (jsonwebtoken — most common)
    import jwt from "jsonwebtoken";
    
    const decoded = jwt.decode(token);                 // unverified
    const verified = jwt.verify(token, secret);         // throws if invalid
    
    // Browser (jose — modern, no deps)
    import * as jose from "jose";
    
    const decoded = jose.decodeJwt(token);
    const { payload } = await jose.jwtVerify(token, await jose.importJWK(jwk));
    
    // Python (PyJWT)
    import jwt
    decoded = jwt.decode(token, secret, algorithms=["HS256"])
    
    // Manual decode (browser, no library)
    const [header, payload] = token.split(".").slice(0, 2)
      .map(seg => JSON.parse(atob(seg.replace(/-/g, "+").replace(/_/g, "/"))));

    When NOT to use JWT

    • For session storage. Sessions you need to revoke instantly are better as opaque session IDs in a database. JWT revocation requires a denylist that defeats the stateless benefit.
    • For sensitive payload data. Anyone with the token reads the claims. Store sensitive data server-side and reference by ID in the JWT instead.
    • For very long expiry. If your tokens last weeks, you’ve reinvented session storage with extra steps. Use refresh tokens with short-lived JWTs.
    • When you need cookie-based CSRF protection. JWTs in localStorage are vulnerable to XSS; in cookies they’re vulnerable to CSRF. Each pattern has trade-offs to design around.

    Frequently asked questions

    Is JWT encrypted?

    Standard JWT (JWS) is signed but not encrypted — anyone with the token can decode and read the payload. JWE (JSON Web Encryption) is the encrypted variant, much less common. Don’t put secrets in JWT claims.

    Can I decode a JWT without the secret?

    Yes. The header and payload are Base64-URL encoded — anyone can decode them. The secret is only needed to verify the signature (prove the token wasn’t forged) or to create a new token. Decoding without verification is fine for inspection but never trust an unverified JWT in production.

    How long should a JWT expire?

    15-60 minutes for access tokens. Pair with a refresh token (longer expiry, revocable, server-side stored) for sustained sessions. Short access-token expiry limits damage if a token is leaked.

    Is my JWT sent to your server when I decode it?

    No. Decoding happens entirely in your browser via the Web Crypto API and JavaScript Base64 decoding. The token, secret (if you paste one), and decoded output all stay on your device. Verify in DevTools Network tab — no requests during decoding.

    What’s the difference between HS256 and RS256?

    HS256 uses a shared secret known to signer and verifier (symmetric). RS256 uses an RSA key pair where the issuer holds the private key and verifiers use the public key (asymmetric). Use HS256 for one-service contexts, RS256 for distributed/multi-service auth.

    Can I edit a JWT and re-sign it?

    Yes — switch to Encode mode, edit the header or payload JSON, paste the secret, click Sign. The output is a new valid JWT. Useful for testing token-validation logic with custom payloads.

    Related tools and guides

     

  • HTML Minifier: Compress HTML Safely in Browser [2026]

    HTML Minifier: Compress HTML Safely in Browser [2026]

    TL;DR: An HTML minifier removes whitespace, comments, redundant attribute quotes, and (optionally) minifies inline <style> and <script> blocks. Typical pages shrink 20–35% pre-gzip. Use it on static pages, email templates, and AMP documents — but skip it on server-rendered HTML where bytes matter less than build complexity. Our free HTML minifier runs html-minifier-terser in your browser with safe defaults you can override.

    HTML is the easiest place to leave bytes on the floor. Hand-authored markup carries indentation, comments, optional closing tags (</li>, </p>), and quoted attributes that could be unquoted. A 112 KB hand-written page minifies to 78 KB (−30%); add gzip and you’re at roughly 18 KB on the wire. For a marketing landing page or an email template that ships unchanged for months, those savings compound across every visit.

    Our HTML minifier wraps html-minifier-terser — the de-facto Node.js engine since 2017 — and runs it entirely in your browser. It minifies inline CSS via csso and inline JS via Terser, both included. This guide covers what’s safe to strip, what to leave alone, and the gotchas that turn perfectly valid HTML into broken markup.

    What HTML minification removes (and the size impact)

    Transform Example Savings
    Collapse whitespace Indentation between tags 10–25%
    Remove comments <!-- ... --> 2–8%
    Drop optional tags </li> at end of <li> 1–3%
    Unquote attributes id="x"id=x 1–2%
    Drop redundant attrs type="text" on <input> <1%
    Boolean attribute collapse disabled="disabled"disabled <1%
    Minify inline CSS csso on <style> blocks 3–10% (depends on CSS)
    Minify inline JS Terser on <script> blocks 3–8% (depends on JS)

    Safe vs aggressive: which options to enable

    html-minifier-terser exposes about 30 boolean flags. Most are safe; a handful change rendering or break edge cases. Our default preset turns on these safe options:

    • collapseWhitespace — strip indentation between tags. Won’t collapse whitespace inside <pre>, <textarea>, or content marked with white-space: pre.
    • removeComments — strip <!-- ... -->. Preserves IE conditionals (<!--[if IE]>) and lines marked with <!-- ! -->.
    • removeRedundantAttributes — drops type="text", method="get", etc.
    • collapseBooleanAttributeschecked="checked"checked.
    • minifyCSS + minifyJS — minify inline blocks.

    Options to enable only with care:

    • removeOptionalTags — drops </li>, </p>, </td>. Valid HTML5 but breaks XML-strict tooling and some legacy parsers.
    • removeAttributeQuotes — saves a few bytes but breaks if an attribute value contains spaces or special characters.
    • conservativeCollapse — preserves a single space at edges where collapsing might affect rendering. Safer but smaller savings.

    How to minify HTML in your browser

    1. Open the HTML minifier
    2. Paste your HTML or drop in an .html file
    3. Pick the preset: Safe (default), Aggressive, or Email-template-safe
    4. Click Minify — output appears with before/after sizes
    5. Copy or download as .min.html

    Email-template gotchas

    HTML emails are the wild west: Outlook 2016 still parses HTML4 with quirks, Gmail strips <style> blocks under certain conditions, and Apple Mail rendering disagrees with iOS Mail in subtle ways. Aggressive minification breaks emails in ways that don’t show up in DesktopGmail but break in Outlook. Use the Email-template-safe preset, which:

    • Keeps all attribute quotes (Outlook chokes on unquoted)
    • Preserves IE conditional comments (<!--[if mso]>)
    • Doesn’t drop optional tags
    • Doesn’t minify inline CSS (some clients require expanded CSS)
    • Preserves <!--[if !mso]> and mso-* proprietary attributes

    Test minified email templates with Litmus or Email on Acid before sending; visual inspection in Gmail web won’t catch Outlook breakage.

    Common gotchas

    • Whitespace inside <pre> and <textarea> is significant. Minifiers preserve it by default; verify your output if you’ve added unusual elements with white-space: pre styling.
    • Inline templates (Vue, Handlebars, JSX) can break. Whitespace between adjacent text nodes carries meaning in some templating languages. Minify the rendered output, not the template source.
    • Attribute order changes. Some minifiers reorder attributes alphabetically. If you have CSS or JS that depends on attribute order (rare but real), turn that off.
    • JSON-LD inside <script type="application/ld+json"> is preserved. Minifiers shouldn’t touch JSON-LD content, but a buggy minifier may strip its leading whitespace and break parsing. Verify schema validates after minifying.
    • Don’t minify HTML you’ll edit later. Minified HTML is unreadable. Keep the source, generate the minified output as a build artefact, and never commit minified HTML to your repo unless that’s your only deployment artefact.
    • Multi-byte characters get corrupted by some legacy minifiers. html-minifier-terser handles UTF-8 correctly. Older “html-tidy” tools strip emoji and non-Latin characters silently.

    When NOT to use a browser HTML minifier

    For server-rendered apps (Next.js, Nuxt, Remix, SvelteKit, Astro), HTML minification is automatic in production builds. For static site generators (Eleventy, Hugo, Jekyll), it’s a single config flag. For email templates, install html-minifier-terser locally and run it as part of your build with the email-safe preset baked in. Use this browser tool for one-off pages, snippets pasted from a CMS, AMP pages prepared by hand, and email templates you edit visually.

    Frequently asked questions

    Is minified HTML still valid?

    Yes — html-minifier-terser produces valid HTML5. Even with optional-tag removal, the output passes the W3C validator. The exception is removeAttributeQuotes, which produces non-quoted attribute values that some old browsers (IE6/7) don’t handle correctly. Stick to the safe preset for maximum compatibility.

    How much will gzip add on top of HTML minification?

    Roughly another 60–70%. A 78 KB minified HTML file gzips to about 22 KB. HTML compresses extremely well because of repeated tag names and attribute values. Always serve .html with Content-Encoding: gzip or br.

    Will minification break my Schema.org JSON-LD?

    No — html-minifier-terser preserves <script type="application/ld+json"> contents intact. The JSON inside is passed through unchanged. If your schema breaks after minifying, the issue is elsewhere — usually whitespace stripping outside the script tag concatenating two adjacent script blocks.

    Can I minify HTML emails for Mailchimp or SendGrid?

    Yes, but use the email-template-safe preset. Modern email clients tolerate minified HTML, but Outlook 2016 and earlier choke on unquoted attributes and missing optional tags. Test in Litmus before sending.

    Is my HTML uploaded?

    No. The minifier runs in your browser via WebAssembly. Pasted markup never reaches our servers — useful when minifying pre-release pages, internal docs, or email templates with proprietary content.

    What’s the difference between an HTML minifier and a CSS minifier?

    HTML minifiers strip whitespace and tags from markup; CSS minifiers strip whitespace and shorten selectors inside stylesheets. Our HTML minifier also minifies inline <style> and <script> blocks, so for a single HTML file with embedded CSS/JS, one pass through the HTML minifier handles everything.

    Related tools and guides