Clever Quest Lab Tools

Online Notepad

2026-10-17

Write notes in a plain, distraction-free editor that saves every change in your browser as you type. Keep as many notes as you like, search them, preview simple formatting, see a live word count and download any note as a TXT, Markdown or HTML file.

Your notes

Saved

Notes stay only in this browser on this device. Nothing is uploaded. Export a note to keep a copy.

    Words: 0 Characters: 0 Reading time: 0 min

    Export this note: Import:

    Ctrl+S saves now (Cmd on Mac) · Ctrl+B bold · Ctrl+I italic

    How to use the online notepad

    1. Click in the big text area and start typing. There is no save button to press: the status badge changes to "Saving…" and then to "Saved" about half a second after you stop.
    2. Give the note a title in the field above the text. The title appears in the list on the left and is used as the file name when you export.
    3. Press + New note to start another note. Click any note in the list to switch to it. The search box filters the list by title and text.
    4. Use Edit and Preview to switch between writing and reading the formatted result.
    5. To remove a note press Delete note. A bar appears with an Undo button, so a slip of the finger is not final.
    6. Under the text, use TXT, Markdown or HTML to download the current note, or Open .txt / .md file to bring a file in as a new note.

    How autosave works

    The notepad keeps all of your notes in one record in your browser's localStorage, a small storage area that every website gets for itself. Each change is written there shortly after you stop typing, and once more when you switch notes, press Ctrl+S or leave the page. When you come back later in the same browser, the notes are read from that record and appear exactly as you left them.

    This has two consequences that are worth knowing. First, nothing is sent to a server, so the notes are private, but there is also no copy anywhere else. Second, the notes belong to one browser profile on one device. A different browser, a different computer or a phone will show an empty notepad. Browsers usually allow about 5 MB of localStorage per site, which is millions of words of plain text, but if the limit is ever reached the page tells you that the latest changes were not saved.

    If the browser refuses to store data at all, for example in some private windows or when site data is blocked, the badge shows "Not saved" and a warning explains what happened.

    Formatting with Markdown

    The editor is plain text, so there is no hidden formatting and nothing strange happens when you copy the text elsewhere. To add emphasis, headings or lists you type a few simple marks, called Markdown, and the Preview button shows the result. The buttons above the text (B, I, H, List, Link) insert the marks for you, and Ctrl+B and Ctrl+I work inside the text area.

    You typePreview shows
    **bold**bold text
    *italic*italic text
    ## Headinga heading (one to six # signs set the level)
    - itema bulleted list
    1. itema numbered list
    - [ ] taska list item with an empty box (use [x] for a ticked box)
    > quotean indented quotation
    `code`text in a code font
    [text](https://example.com)a link that opens in a new tab
    ---a horizontal line

    Line breaks are kept as you type them, and a blank line starts a new paragraph. Nested lists and tables are not supported. The preview never runs scripts: any HTML you type is shown as plain text, and only links starting with http://, https:// or mailto: become clickable.

    Word count, character count and reading time

    Below the text area the page counts three things. Words are groups of characters separated by spaces or line breaks, so "well-known" counts as one word and "e-mail" as one. Characters counts every character including spaces and line breaks. Reading time divides the word count by 200 words per minute and rounds up to a whole minute, so any note with at least one word shows at least "~1 min".

    Examples

    Example 1: counting. Type Buy milk, eggs and bread. The page shows 5 words and 25 characters (19 letters, 2 punctuation marks and 4 spaces) and a reading time of ~1 min.

    Example 2: reading time. A note of 400 words divided by 200 words per minute is exactly 2 minutes, so the page shows ~2 min. A note of 450 words gives 2.25 minutes, which is rounded up to ~3 min.

    Example 3: formatting. Type ## Shopping on one line and - milk and - **eggs** on the next two lines. In Preview you see a heading "Shopping" followed by a bulleted list with "milk" and a bold "eggs".

    Example 4: exporting. A note titled "Meeting notes 12 Oct" is downloaded as meeting-notes-12-oct.txt, meeting-notes-12-oct.md or meeting-notes-12-oct.html. The TXT and Markdown files contain the text exactly as typed; the HTML file contains the title as a heading and the formatted note below it.

    Export, import and backups

    Because the notes live only in your browser, the safest habit is to export the notes that matter. TXT opens in every editor on every system. Markdown keeps the formatting marks and works in many note and documentation tools. HTML is a ready-to-read web page with a light background.

    To bring text in, press Open .txt / .md file and choose a file. It becomes a new note named after the file. Files must be plain text and no larger than 1 MB; other file types are not converted.

    Keeping your notes safe

    Frequently asked questions

    Does it save automatically?

    Yes. Every change is stored in your browser a moment after you stop typing. Ctrl+S saves immediately and confirms it below the notes, but it does not download a file; use the export buttons for that.

    How many notes can I keep?

    There is no fixed number. The limit is the storage space your browser gives the site, usually about 5 MB in total, which is enough for a very large number of ordinary text notes.

    Why did my notes disappear?

    The usual reasons are cleared site data, a private window, a different browser or profile, or a different device. The notes are not stored anywhere else, which is why exporting a copy of important notes is recommended.

    Can I undo a deleted note?

    Yes, with the Undo button that appears right after deleting. It stays for a while, but once you dismiss it or delete another note, or when you close the page, the earlier note is gone for good. Inside the text area, Ctrl+Z undoes typing as usual.

    Is anything uploaded or shared?

    No. Your notes, titles, searches and imported files stay in your browser on your device. The page makes no requests that carry your text, and nobody else can read the notes unless they use your browser profile.

    Related tools

    \n\n'; download(base + '.html', 'text/html;charset=utf-8', doc); } msg('Exported ' + base + '.' + kind + '. Check your downloads folder.'); } function importFile(file) { if (!file) return; if (file.size > MAX_IMPORT) { msg('That file is larger than 1 MB, so it was not imported.'); return; } function done(txt) { if (txt.indexOf('\u0000') !== -1) { msg('That file does not look like plain text, so it was not imported.'); return; } var name = file.name.replace(/\.(txt|md|markdown)$/i, ''); addNote(name, txt.replace(/\r\n?/g, '\n')); msg('Imported “' + file.name + '” as a new note.'); } if (file.text) file.text().then(done, function () { msg('The file could not be read.'); }); else { var fr = new FileReader(); fr.onload = function () { done(String(fr.result)); }; fr.onerror = function () { msg('The file could not be read.'); }; fr.readAsText(file); } } /* ---------- formatting helpers (plain-text Markdown syntax) ---------- */ function insertAt(start, end, str, selStart, selEnd) { el.text.focus(); el.text.setSelectionRange(start, end); var ok = false; try { ok = document.execCommand('insertText', false, str); } catch (e) { ok = false; } if (!ok) { el.text.setRangeText(str, start, end, 'end'); el.text.dispatchEvent(new Event('input', { bubbles: true })); } el.text.setSelectionRange(selStart, selEnd); } function wrap(mark) { var v = el.text.value, s = el.text.selectionStart, e = el.text.selectionEnd; var sel = v.slice(s, e), L = mark.length; if (sel && sel.length >= 2 * L && sel.slice(0, L) === mark && sel.slice(-L) === mark) { var inner = sel.slice(L, sel.length - L); insertAt(s, e, inner, s, s + inner.length); } else if (!sel && v.slice(s - L, s) === mark && v.slice(s, s + L) === mark) { insertAt(s - L, s + L, '', s - L, s - L); } else { insertAt(s, e, mark + sel + mark, s + L, s + L + sel.length); } } function lineRange() { var v = el.text.value, s = el.text.selectionStart, e = el.text.selectionEnd; var a = v.lastIndexOf('\n', s - 1) + 1; var b = v.indexOf('\n', e > s && v.charAt(e - 1) === '\n' ? e - 1 : e); if (b === -1) b = v.length; return [a, b]; } function heading() { var r = lineRange(), block = el.text.value.slice(r[0], r[1]); var out = block.split('\n').map(function (l) { return /^##\s/.test(l) ? l.replace(/^##\s/, '') : '## ' + l.replace(/^#{1,6}\s/, ''); }).join('\n'); insertAt(r[0], r[1], out, r[0], r[0] + out.length); } function bullets() { var r = lineRange(), block = el.text.value.slice(r[0], r[1]); var ls = block.split('\n'); var all = ls.every(function (l) { return /^\s*[-*+]\s/.test(l); }); var out = ls.map(function (l) { return all ? l.replace(/^(\s*)[-*+]\s/, '$1') : '- ' + l; }).join('\n'); insertAt(r[0], r[1], out, r[0], r[0] + out.length); } function link() { var s = el.text.selectionStart, e = el.text.selectionEnd, sel = el.text.value.slice(s, e) || 'link text'; var u = s + sel.length + 3; insertAt(s, e, '[' + sel + '](https://)', u, u + 8); } /* ---------- events ---------- */ el.text.addEventListener('input', function () { var n = find(cur); n.text = el.text.value; renderStats(); changed(); }); el.title.addEventListener('input', function () { var n = find(cur); n.title = el.title.value; changed(); renderList(); }); el.search.addEventListener('input', function () { query = el.search.value.trim(); renderList(); }); el.list.addEventListener('click', function (e) { var b = e.target.closest ? e.target.closest('.np-item') : null; if (b) select(b.getAttribute('data-id'), true); }); el.nw.addEventListener('click', function () { addNote('', ''); el.title.focus(); msg('New note created. Give it a title or start typing.'); }); el.del.addEventListener('click', deleteNote); el.undoBtn.addEventListener('click', undoDelete); el.undoClose.addEventListener('click', function () { hideUndo(); el.nw.focus(); }); el.modeEdit.addEventListener('click', function () { mode = 'edit'; applyMode(); save(); el.text.focus(); }); el.modePrev.addEventListener('click', function () { mode = 'preview'; applyMode(); save(); }); $('np-b').addEventListener('click', function () { wrap('**'); }); $('np-i').addEventListener('click', function () { wrap('*'); }); $('np-h').addEventListener('click', heading); $('np-ul').addEventListener('click', bullets); $('np-a').addEventListener('click', link); $('np-ex-txt').addEventListener('click', function () { exportNote('txt'); }); $('np-ex-md').addEventListener('click', function () { exportNote('md'); }); $('np-ex-html').addEventListener('click', function () { exportNote('html'); }); el.imp.addEventListener('click', function () { el.file.click(); }); el.file.addEventListener('change', function () { var f = el.file.files && el.file.files[0]; importFile(f); el.file.value = ''; }); document.addEventListener('keydown', function (e) { if (!(e.ctrlKey || e.metaKey) || e.altKey) return; var k = e.key.toLowerCase(); if (k === 's') { e.preventDefault(); if (save()) { renderList(); msg('Saved in this browser. Use the export buttons to download a copy.'); } else msg('Could not save in this browser. Export the note to keep it.'); } else if ((k === 'b' || k === 'i') && document.activeElement === el.text) { e.preventDefault(); wrap(k === 'b' ? '**' : '*'); } }); window.addEventListener('pagehide', flush); document.addEventListener('visibilitychange', function () { if (document.hidden) flush(); }); window.addEventListener('storage', function (e) { if (e.key !== KEY || dirty || !e.newValue) return; try { var d = JSON.parse(e.newValue); if (!d || !Array.isArray(d.notes) || !d.notes.length) return; notes = clean(d.notes); if (!notes.length) return; if (!find(cur)) cur = notes[0].id; showNote(); msg('Notes were updated from another tab.'); } catch (err) { /* ignore */ } }); load(); showNote(); if (storageOk) save(); })();