DOCUMENT CONVERTER

Universal Document
Converter

Seamlessly convert between PDF, DOCX, HTML, and TXT formats. Every conversion happens instantly in your browser — no files are uploaded to any server.

🔒
100% Private
No Upload Required
Instant Conversion
1
Upload
2
Format
3
Convert

Drag & drop your file here

or click to browse from your computer

PDF DOCX HTML TXT
Unsupported file type. Please upload a PDF, DOCX, HTML, or TXT file.
PDF
document.pdf
2.4 MB · PDF Document
PDF
PDF Portable Document Format
DOCX
DOCX Word Document
HTML
HTML Web Page Format
TXT
TXT Plain Text
Advanced Settings
PDF Output Options
Page Size
Set the document page dimensions
Image Quality
Controls compression and clarity
90%
Include Images
Extract and embed images in the output
DOCX Output Options
Preserve Formatting
Keep original styles, fonts, and layout
Text Output Options
Line Spacing
Number of blank lines between paragraphs
Include Page Numbers
Add page markers where pages break
Converting... 0%

Conversion Complete!

Your file has been converted successfully.

PDF
Output Format
1.2 MB
File Size
2.1s
Conversion Time
Preview
Converted content will appear here...

Powerful Features, Simple Design

Everything you need for fast, reliable document conversions — right in your browser.

📄

Multi-Format Support

Convert seamlessly between PDF, DOCX, HTML, and TXT. All major document formats are supported with high fidelity output.

🎨

Preserve Quality

Advanced rendering ensures your converted documents maintain original formatting, fonts, images, and layout structure.

📦

Batch Convert

Process multiple files at once with batch conversion. Save time by converting entire document collections in a single session.

Instant Processing

Lightning-fast conversions powered by modern browser APIs. No waiting for server queues — your files convert in real-time.

🔒

Secure & Private

Your documents never leave your device. All processing happens locally in your browser — zero data uploads, zero tracking.

💻

Cross-Platform

Works on any device with a modern browser — Windows, Mac, Linux, iOS, and Android. No installation or sign-up needed.

Frequently Asked Questions

Got questions? We've got answers about our document converter tool.

Is my data safe when using this converter?
Absolutely. All document processing happens entirely within your browser using client-side JavaScript. Your files are never uploaded to any server, never stored, and never shared with third parties. Once you close the tab, all data is gone.
What file formats are supported?
The converter supports PDF, DOCX (Microsoft Word), HTML, and TXT (plain text) as both input and output formats. You can convert between any combination of these formats. Supported conversions include PDF to DOCX, DOCX to PDF, HTML to PDF, PDF to HTML, TXT to PDF, and more.
Is there a file size limit?
Since processing happens in your browser, the limit depends on your device's available memory. Most modern devices can handle files up to 50-100 MB without issues. For very large files, you may experience slower performance depending on your hardware.
Does it work on mobile devices?
Yes! The converter is fully responsive and works on smartphones and tablets. You can drag and drop files on mobile (or use the file picker), select your output format, and download the converted file — all from your mobile browser.
Will formatting be preserved during conversion?
We strive to maintain the highest fidelity possible. Text formatting (bold, italic, headings), lists, tables, and images are preserved in most conversions. Note that complex layouts with advanced features may have minor differences due to format limitations.
Is this tool free to use?
Yes, the document converter is 100% free with no limits on the number of conversions. There are no hidden fees, no premium tiers, and no account required. Just open the tool and start converting your documents instantly.
'; for (let i = 1; i <= pdf.numPages; i++) { if (i > 1) html += '
'; const page = await pdf.getPage(i); const textContent = await page.getTextContent(); let lastY = null, currentBlock = ''; const processItems = async () => { for (const item of textContent.items) { const y = Math.round(item.transform[5]); if (lastY !== null && Math.abs(y - lastY) > 5) { html += currentBlock; currentBlock = ''; } lastY = y; const text = item.str; if (item.fontName && item.fontName.toLowerCase().includes('bold') && text.trim()) { currentBlock += '' + escHtml(text) + ''; } else { currentBlock += escHtml(text); } if (item.hasEOL) currentBlock += '
'; } html += currentBlock; }; await processItems(); updateProgress(20 + Math.round((i / pdf.numPages) * 70)); } html += ''; return new Blob([html], { type: 'text/html;charset=utf-8' }); } // --- PDF → TXT --- async function pdfToTxt(buffer) { const pdf = await pdfjsLib.getDocument({ data: buffer }).promise; let text = ''; for (let i = 1; i <= pdf.numPages; i++) { const page = await pdf.getPage(i); const tc = await page.getTextContent(); let lastY = null; for (const item of tc.items) { const y = Math.round(item.transform[5]); if (lastY !== null && Math.abs(y - lastY) > 12) text += '\n'; text += item.str; if (item.hasEOL) text += '\n'; lastY = y; } text += '\n\n--- Page ' + i + ' ---\n\n'; updateProgress(20 + Math.round((i / pdf.numPages) * 70)); } return new Blob([text], { type: 'text/plain;charset=utf-8' }); } // --- PDF → DOCX --- async function pdfToDocx(buffer) { const html = await pdfToHtml(buffer); updateProgress(80); const htmlText = await html.text(); return await htmlStringToDocx(htmlText); } // --- DOCX → HTML (mammoth.js) --- async function docxToHtml(buffer) { const options = { convertImage: mammoth.images.imgElement(function(image) { return image.read("base64").then(function(imageBuffer) { return { src: "data:" + image.contentType + ";base64," + imageBuffer }; }); }) }; const result = await mammoth.convertToHtml({ arrayBuffer: buffer }, options); const fullHtml = ' ' + result.value + ''; updateProgress(90); return new Blob([fullHtml], { type: 'text/html;charset=utf-8' }); } // --- DOCX → TXT --- async function docxToTxt(buffer) { const result = await mammoth.extractRawText({ arrayBuffer: buffer }); updateProgress(90); return new Blob([result.value], { type: 'text/plain;charset=utf-8' }); } // --- DOCX → PDF --- async function docxToPdf(buffer) { const html = await docxToHtml(buffer); updateProgress(70); return await htmlBlobToPdf(html); } // --- HTML → PDF --- async function htmlToPdf(buffer) { const decoder = new TextDecoder('utf-8'); const htmlStr = decoder.decode(buffer); updateProgress(40); // Parse out body content const parser = new DOMParser(); const doc = parser.parseFromString(htmlStr, 'text/html'); const body = doc.body; if (!body) throw new Error('Invalid HTML: no body found'); // Extract styles const styles = doc.querySelectorAll('style'); let styleStr = ''; styles.forEach(s => styleStr += s.textContent); const contentHtml = '
' + body.innerHTML + '
'; // Create temp element const tmp = document.createElement('div'); tmp.innerHTML = contentHtml; tmp.style.cssText = 'position:fixed;left:-9999px;top:0;width:800px;background:#fff;padding:20px;font-family:system-ui,sans-serif;color:#1e293b;'; document.body.appendChild(tmp); updateProgress(60); const opt = { margin: [10,10,10,10], filename: 'converted.pdf', image: { type: 'jpeg', quality: state.settings.quality / 100 }, html2canvas: { scale: 2, useCORS: true, logging: false }, jsPDF: { unit: 'mm', format: 'a4', orientation: state.settings.orientation }, pagebreak: { mode: ['avoid-all', 'css', 'legacy'] } }; const blob = await html2pdf().set(opt).from(tmp).outputPdf('blob'); document.body.removeChild(tmp); updateProgress(95); return blob; } // --- HTML → TXT --- async function htmlToTxt(buffer) { const decoder = new TextDecoder('utf-8'); const htmlStr = decoder.decode(buffer); const tmp = document.createElement('div'); tmp.innerHTML = htmlStr; const text = (tmp.textContent || tmp.innerText || '').replace(/\n\s*\n\s*\n/g, '\n\n').trim(); updateProgress(90); return new Blob([text], { type: 'text/plain;charset=utf-8' }); } // --- HTML → DOCX --- async function htmlToDocx(buffer) { const decoder = new TextDecoder('utf-8'); const htmlStr = decoder.decode(buffer); updateProgress(40); return await htmlStringToDocx(htmlStr); } // --- TXT → PDF --- async function txtToPdf(buffer) { const decoder = new TextDecoder('utf-8'); const text = decoder.decode(buffer); const escapedText = escHtml(text).replace(/\n/g, '
'); const htmlStr = ' ' + escapedText + ''; updateProgress(50); const tmp = document.createElement('div'); tmp.innerHTML = '
' + escapedText + '
'; tmp.style.cssText = 'position:fixed;left:-9999px;top:0;'; document.body.appendChild(tmp); updateProgress(70); const opt = { margin: [15,15,15,15], filename: 'converted.pdf', html2canvas: { scale: 2, logging: false }, jsPDF: { unit: 'mm', format: 'a4', orientation: state.settings.orientation } }; const blob = await html2pdf().set(opt).from(tmp).outputPdf('blob'); document.body.removeChild(tmp); updateProgress(95); return blob; } // --- TXT → DOCX --- async function txtToDocx(buffer) { const decoder = new TextDecoder('utf-8'); const text = decoder.decode(buffer); updateProgress(40); return await htmlStringToDocx('

' + escHtml(text).replace(/\n\n/g, '

').replace(/\n/g, '
') + '

'); } // --- TXT → HTML --- async function txtToHtml(buffer) { const decoder = new TextDecoder('utf-8'); const text = decoder.decode(buffer); const htmlStr = ' ' + escHtml(text) + ''; updateProgress(90); return new Blob([htmlStr], { type: 'text/html;charset=utf-8' }); } // --- Utility: HTML blob → PDF blob --- async function htmlBlobToPdf(htmlBlob) { const url = URL.createObjectURL(htmlBlob); const response = await fetch(url); const htmlStr = await response.text(); URL.revokeObjectURL(url); const tmp = document.createElement('div'); tmp.innerHTML = htmlStr; tmp.style.cssText = 'position:fixed;left:-9999px;top:0;width:800px;background:#fff;padding:20px;font-family:system-ui,sans-serif;color:#1e293b;'; document.body.appendChild(tmp); updateProgress(80); const opt = { margin: [10,10,10,10], filename: 'converted.pdf', image: { type: 'jpeg', quality: state.settings.quality / 100 }, html2canvas: { scale: 2, useCORS: true, logging: false }, jsPDF: { unit: 'mm', format: 'a4', orientation: state.settings.orientation }, pagebreak: { mode: ['avoid-all', 'css', 'legacy'] } }; const blob = await html2pdf().set(opt).from(tmp).outputPdf('blob'); document.body.removeChild(tmp); return blob; } // --- Utility: HTML string → DOCX blob --- async function htmlStringToDocx(htmlStr) { const zip = new JSZip(); // Parse HTML const parser = new DOMParser(); const doc = parser.parseFromString(htmlStr, 'text/html'); const body = doc.body; if (!body) throw new Error('Invalid HTML content'); // Build paragraphs array const paragraphs = []; const children = body.childNodes; children.forEach(node => { if (node.nodeType === Node.TEXT_NODE) { const txt = node.textContent.trim(); if (txt) paragraphs.push({ text: txt, bold: false }); } else if (node.nodeType === Node.ELEMENT_NODE) { const tag = node.tagName.toLowerCase(); if (tag === 'p' || tag === 'div' || tag === 'h1' || tag === 'h2' || tag === 'h3' || tag === 'h4' || tag === 'h5' || tag === 'h6' || tag === 'li') { const text = node.textContent.trim(); if (text) { const isBold = tag === 'h1' || tag === 'h2' || tag === 'h3'; const fs = tag === 'h1' ? 28 : tag === 'h2' ? 24 : tag === 'h3' ? 20 : state.settings.fontSize * 2; paragraphs.push({ text: text, bold: isBold, size: fs }); } } else if (tag === 'table') { const rows = []; node.querySelectorAll('tr').forEach(tr => { const cells = []; tr.querySelectorAll('td, th').forEach(td => cells.push(td.textContent.trim())); if (cells.length) rows.push(cells); }); if (rows.length) paragraphs.push({ type: 'table', rows: rows }); } else if (tag === 'img') { const src = node.getAttribute('src') || ''; paragraphs.push({ type: 'image', src: src }); } else if (tag === 'br') { paragraphs.push({ text: '', bold: false }); } else { const text = node.textContent.trim(); if (text) paragraphs.push({ text: text, bold: false }); } } }); // Generate docx XML let bodyXml = ''; paragraphs.forEach(p => { if (p.type === 'table') { bodyXml += ''; p.rows.forEach((row, ri) => { bodyXml += ''; row.forEach(cell => { bodyXml += ''; if (ri === 0) bodyXml += ''; bodyXml += '' + escXml(cell) + ''; }); bodyXml += ''; }); bodyXml += ''; } else if (p.type === 'image') { // Add image placeholder text bodyXml += '[Image]'; } else { const sz = p.size ? Math.round(p.size * 2) : Math.round(state.settings.fontSize * 2); const b1 = p.bold ? '' : ''; const b2 = p.bold ? '' : ''; bodyXml += '' + b1 + b2 + '' + escXml(p.text) + ''; } }); const contentTypes = '\n'; const rels = '\n'; const wordRels = '\n'; const documentXml = '\n' + bodyXml + ''; zip.file('[Content_Types].xml', contentTypes); zip.file('_rels/.rels', rels); zip.file('word/_rels/document.xml.rels', wordRels); zip.file('word/document.xml', documentXml); updateProgress(85); const blob = await zip.generateAsync({ type: 'blob', mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' }); return blob; } function escXml(s) { return s.replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); } // --- Init --- function init() { initTheme(); initFAQ(); // Theme toggles $$('.theme-toggle').forEach(btn => btn.addEventListener('click', toggleTheme)); // Hamburger const ham = $('.hamburger'); if (ham) ham.addEventListener('click', toggleMobileNav); $$('.mobile-nav-link').forEach(link => link.addEventListener('click', () => { toggleMobileNav(); })); // Upload zone — click const zone = $('.upload-zone'); if (zone) { zone.addEventListener('click', (e) => { if (e.target.closest('.file-remove-btn')) return; const input = document.createElement('input'); input.type = 'file'; input.accept = '.pdf,.docx,.doc,.html,.htm,.txt,.text,.md'; input.onchange = (e) => { if (e.target.files[0]) handleFile(e.target.files[0]); }; input.click(); }); // Drag & drop zone.addEventListener('dragover', (e) => { e.preventDefault(); zone.classList.add('dragover'); }); zone.addEventListener('dragleave', () => zone.classList.remove('dragover')); zone.addEventListener('drop', (e) => { e.preventDefault(); zone.classList.remove('dragover'); if (e.dataTransfer.files[0]) handleFile(e.dataTransfer.files[0]); }); } // File remove const removeBtn = document.querySelector('.file-remove-btn'); if (removeBtn) removeBtn.addEventListener('click', (e) => { e.stopPropagation(); removeFile(); }); // Format cards $$('.format-card').forEach(card => { card.addEventListener('click', () => selectFormat(card.dataset.format)); }); // Settings toggle const settingsHeader = $('.settings-header'); if (settingsHeader) settingsHeader.addEventListener('click', toggleSettings); // Range slider value display $$('.range-slider input[type="range"]').forEach(slider => { const valEl = slider.closest('.range-slider').querySelector('.range-value'); if (valEl) { valEl.textContent = slider.value; slider.addEventListener('input', () => { valEl.textContent = slider.value; state.settings.quality = parseInt(slider.value); }); } }); // Settings toggles $$('input[name="preserveImages"]').forEach(el => el.addEventListener('change', () => { state.settings.preserveImages = el.checked; })); $$('input[name="preserveTables"]').forEach(el => el.addEventListener('change', () => { state.settings.preserveTables = el.checked; })); $$('select[name="orientation"]').forEach(el => el.addEventListener('change', () => { state.settings.orientation = el.value; })); $$('select[name="fontSize"]').forEach(el => el.addEventListener('change', () => { state.settings.fontSize = parseInt(el.value); })); // Convert button const convertBtn = document.querySelector('.convert-btn'); if (convertBtn) convertBtn.addEventListener('click', startConversion); // Reset button const resetBtn = document.querySelector('.reset-btn'); if (resetBtn) resetBtn.addEventListener('click', resetConverter); // Year const yearEl = $('#currentYear'); if (yearEl) yearEl.textContent = new Date().getFullYear(); } // Start if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();