{"id":15709,"library":"mowdown","title":"mowdown: HTML, CSS, and JS Production Bundler","description":"Mowdown is a lightweight, standalone JavaScript bundler designed for straightforward production preparation of web applications. Currently at version 2.2.2, it provides a minimal approach to consolidating and optimizing HTML, CSS, and JavaScript assets without requiring complex build configurations or a persistent local server process. The tool operates by scanning specified HTML files, identifying local CSS and JavaScript references (via `<link>` and `<script>` tags), and then concatenating, minifying, and optionally applying Babel transformations to these assets. Its primary differentiator is its simplicity and \"no build step\" philosophy, aiming to reduce developer overhead by working directly with existing HTML structures rather than introducing module systems or advanced optimizations like tree shaking or code splitting. It is suitable for projects where the build process needs to be minimal and predictable, especially for static sites or simple web applications. It operates purely as a Node.js utility.","status":"active","version":"2.2.2","language":"javascript","source_language":"en","source_url":"ssh://git@github.com/andrewfulrich/mowdown","tags":["javascript","minify"],"install":[{"cmd":"npm install mowdown","lang":"bash","label":"npm"},{"cmd":"yarn add mowdown","lang":"bash","label":"yarn"},{"cmd":"pnpm add mowdown","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The package is a CommonJS module. Using 'import' syntax directly may require bundler configuration or explicit transpilation in some environments.","wrong":"import mowdown from 'mowdown'","symbol":"mowdown","correct":"const mowdown = require('mowdown')"},{"note":"The 'mowdown' export is a function that you call directly, not a class to instantiate with 'new'.","wrong":"new mowdown(arrayOfHtmlFiles, outputFolder, options)","symbol":"mowdown (function call)","correct":"mowdown(arrayOfHtmlFiles, outputFolder, options)"}],"quickstart":{"code":"const mowdown = require('mowdown');\nconst fs = require('fs');\nconst path = require('path');\n\n// Create temporary input and output directories\nconst inputDir = path.join(__dirname, 'temp_mowdown_input');\nconst outputDir = path.join(__dirname, 'temp_mowdown_output');\nfs.mkdirSync(inputDir, { recursive: true });\nfs.mkdirSync(outputDir, { recursive: true });\n\n// Create dummy HTML, CSS, JS files for bundling\nconst htmlContent = `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Mowdown Test</title>\n    <link rel=\"stylesheet\" href=\"style.css\">\n</head>\n<body>\n    <h1>Welcome to Mowdown!</h1>\n    <script src=\"script.js\"></script>\n</body>\n</html>`;\nconst cssContent = `body { font-family: 'Arial', sans-serif; background-color: #e0f2f7; } h1 { color: #0277bd; text-align: center; }`;\nconst jsContent = `document.addEventListener('DOMContentLoaded', () => {\n    console.log('JavaScript processed by mowdown!');\n    const heading = document.querySelector('h1');\n    if (heading) heading.textContent = 'Mowdown has bundled this content!';\n});`;\n\nfs.writeFileSync(path.join(inputDir, 'index.html'), htmlContent);\nfs.writeFileSync(path.join(inputDir, 'style.css'), cssContent);\nfs.writeFileSync(path.join(inputDir, 'script.js'), jsContent);\n\n// Define a minimal .babelrc required by mowdown\nconst babelrcContent = `{ \"presets\": [\"@babel/preset-env\"] }`;\nfs.writeFileSync(path.join(__dirname, '.babelrc'), babelrcContent);\n\nasync function runBundler() {\n    try {\n        console.log('Running mowdown bundling process...');\n        await mowdown([path.join(inputDir, 'index.html')], outputDir, {\n            sourceFolder: inputDir,\n            isOverwritingHtml: false // Crucial to avoid overwriting original source HTML\n        });\n        console.log(`\n✅ Mowdown finished successfully. Check '${outputDir}' for bundled files.`);\n        \n        // Optional: Verify bundled HTML content\n        const bundledHtmlPath = path.join(outputDir, 'index.html');\n        if (fs.existsSync(bundledHtmlPath)) {\n            const bundledHtmlSnippet = fs.readFileSync(bundledHtmlPath, 'utf-8').substring(0, 500) + '...';\n            console.log('\\nBundled index.html snippet:\\n', bundledHtmlSnippet);\n        }\n    } catch (error) {\n        console.error('\\n❌ Mowdown failed:', error.message);\n    } finally {\n        // Clean up temporary files and directories\n        fs.rmSync(inputDir, { recursive: true, force: true });\n        fs.rmSync(outputDir, { recursive: true, force: true });\n        fs.rmSync(path.join(__dirname, '.babelrc'), { force: true });\n        console.log('\\nCleaned up temporary files and directories.');\n    }\n}\n\nrunBundler();","lang":"javascript","description":"This quickstart demonstrates how to use `mowdown` to bundle and minify HTML, CSS, and JavaScript files from a source directory into an output directory. It creates temporary input files and a minimal `.babelrc` (which mowdown requires), then processes them and cleans up, showcasing basic API usage with options like `sourceFolder` and `isOverwritingHtml`."},"warnings":[{"fix":"For any CDN-hosted CSS links, include their full URLs in both the `excludeCss` and `prependCssUrls` arrays within the options object passed to the `mowdown` function.","message":"Mowdown implicitly assumes all CSS files referenced in HTML are local. If you are using a CDN-hosted CSS file, you must explicitly add it to both the `excludeCss` and `prependCssUrls` options. Failure to do so can lead to build errors, incorrect paths, or missing styles in the bundled output.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Create a `.babelrc` file in your project root. A minimal configuration like `{ \"presets\": [\"@babel/preset-env\"] }` is often sufficient, or you can copy the example from the mowdown repository if you need more specific Babel functionality.","message":"A `.babelrc` configuration file is required in the root directory for mowdown to correctly process JavaScript files, even if the `isUsingBabel` option is set to `false` or if you don't intend to use Babel transformations. Its absence will lead to errors during the bundling process.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always specify a separate `outputFolder` that is distinct from your source HTML files' location, or explicitly set `isOverwritingHtml: false` in the options object passed to the `mowdown` function to ensure original files are preserved.","message":"The `isOverwritingHtml` option defaults to `true`. This means if you do not specify a distinct `outputFolder` or if `outputFolder` is the same as your input HTML file's directory, mowdown will overwrite your original HTML files with the bundled versions. This can lead to accidental data loss.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Ensure a `.babelrc` file exists in your project's root directory. Even a basic configuration like `{ \"presets\": [\"@babel/preset-env\"] }` is required. Verify that necessary Babel packages are available in mowdown's internal dependencies or your project's `node_modules` if you're running locally.","cause":"Mowdown relies on Babel for JavaScript processing, and a `.babelrc` file is missing or misconfigured in the project root.","error":"Error: Cannot find module '@babel/core' (or similar Babel-related error)"},{"fix":"Double-check the paths specified in your HTML `<script src=\"...\">` and `<link href=\"...\">` tags. If your assets are not in the same directory as your HTML files, ensure the `sourceFolder` option is correctly pointing to the directory containing all your asset files.","cause":"Mowdown failed to locate a referenced CSS or JavaScript asset file at the path specified in your HTML relative to the HTML file or the `sourceFolder` option.","error":"Error: ENOENT: no such file or directory, stat 'path/to/my/asset.css'"},{"fix":"Provide a dedicated `outputFolder` that is different from your `sourceFolder` to receive the bundled output, or explicitly set `isOverwritingHtml: false` within the options object passed to the `mowdown` function to prevent source file modification.","cause":"The `isOverwritingHtml` option defaults to `true`, leading to source HTML files being directly modified or replaced if the `outputFolder` is not specified or is the same as the input HTML's directory.","error":"Original HTML files are modified/overwritten unexpectedly or bundled output doesn't match expectations."}],"ecosystem":"npm"}