{"id":30190101,"url":"https://github.com/jlevy/tminify","last_synced_at":"2025-08-12T19:10:18.615Z","repository":{"id":297864167,"uuid":"998128205","full_name":"jlevy/tminify","owner":"jlevy","description":"Standalone, modern HTML/CSS/JS and Tailwind v4 minification for CLI and Python using terser","archived":false,"fork":false,"pushed_at":"2025-07-25T17:05:08.000Z","size":99,"stargazers_count":2,"open_issues_count":3,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-25T22:13:20.079Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jlevy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-07T23:22:05.000Z","updated_at":"2025-07-25T17:05:14.000Z","dependencies_parsed_at":"2025-07-25T22:13:48.608Z","dependency_job_id":null,"html_url":"https://github.com/jlevy/tminify","commit_stats":null,"previous_names":["jlevy/minify-tw-html","jlevy/tminify"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/jlevy/tminify","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jlevy%2Ftminify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jlevy%2Ftminify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jlevy%2Ftminify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jlevy%2Ftminify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jlevy","download_url":"https://codeload.github.com/jlevy/tminify/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jlevy%2Ftminify/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270119580,"owners_count":24530484,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-12T02:00:09.011Z","response_time":80,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-08-12T19:10:13.307Z","updated_at":"2025-08-12T19:10:18.506Z","avatar_url":"https://github.com/jlevy.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tminify\n\nThis is a convenient CLI and Python lib wrapper for\n[html-minifier-terser](https://github.com/terser/html-minifier-terser)\n[Tailwind v4 CLI](https://tailwindcss.com/docs/installation/tailwind-cli)\n\n## Installation\n\nI recommend you [use uv](installation.md):\n\n```shell\nuv tool install --upgrade tminify\n```\n\nRun `--help` for details:\n\n```shell\n$ tminify --help\nusage: tminify [-h] [--version] [--no_minify] [--preflight] [--tailwind] [--verbose] src_html dest_html\n\nHTML minification with Tailwind CSS v4 compilation\n\npositional arguments:\n  src_html       Input HTML file.\n  dest_html      Output HTML file.\n\noptions:\n  -h, --help     show this help message and exit\n  --version      show program's version number and exit\n  --no_minify    Skip HTML minification (only compile Tailwind if present).\n  --preflight    Enable Tailwind's preflight CSS reset (disabled by default to preserve custom styles).\n  --tailwind     Force Tailwind CSS compilation even if CDN script is not present.\n  --verbose, -v  Enable verbose logging.\n\nCLI for HTML minification with Tailwind CSS v4 compilation.\n\nThis script can be used for general HTML minification (including inline CSS/JS) and/or\nTailwind CSS v4 compilation and inlining (replacing CDN script with compiled CSS).\n\nMinification includes:\n- HTML structure: whitespace removal, comment removal\n- Inline CSS: all \u003cstyle\u003e tags and style attributes are minified\n- Inline JavaScript: all \u003cscript\u003e tags are minified (not external JS files)\n\ntminify v0.1.3.dev4+d976d28\n```\n\n## Minification of Static HTML/CSS/JavaScript Pages\n\nThe first use case for tminify is as a CLI or Python function to minify HTML, CSS, and\nJavaScript using html-minifier-terser, the highly configurable, well-tested,\nJavaScript-based HTML minifier.\n\nIt makes this minifier quick to install with uv.\nYou can then use it as a CLI tool or it can be added as a PyPI dependency to a project\nand used as a minification library from Python.\nIt then internally handles (and caches) the Node dependencies.\n\nOnce it is installed, you can just use it on static files with a single command, with no\npackage.json or npm project setup!\n\nInternally, it checks for an npm installation and uses that, raising an error if not\navailable.\nOnce it finds npm, it does its own internal `npm install` of required tools so\nit’s self-contained.\nThe required npm packages are installed locally within the Python site-packages\ndirectory.\n\n## Tailwind v4 Compilation\n\nIn addition to general minification, tminify also compiles Tailwind CSS v4 standalone,\nwithout other project config or setup.\n\nYou might think Tailwind v4 compilation would be as simple as a single CLI command, but\nit seems like it’s not, since the modern Tailwind CLI seems developed around the use\ncase of a full hot-reloading JavaScript app setup.\nThis is fine if that’s the use case, but quite inconvenient if you don’t to set up a\npackage.json and other things and just want to compile and minify a static HTML page.\n\nWith Tailwind, simple zero-build page development is easy via the\n[Play CDN](https://tailwindcss.com/docs/installation/play-cdn).\nTo do this, you put a tag like `\u003cscript\nsrc=\"https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4\"\u003e\u003c/script\u003e` in your code.\n\nHowever, that setup is not recommended by Tailwind for production use due to its poor\nperformance (scanning the whole page at load time to find Tailwind classes).\nThis tool lets you use any Play CDN link so you can “drop in” Tailwind on static web\npages during development.\nOnce you want to minify before publishing it, run tminify, and will detect the Tailwind\nCDN script and compile and inline the production Tailwind CSS necessary for your page\n(and then minify everything else, including HTML and JavaScript).\n\n## Are There Alternatives?\n\nPreviously I had been using the [minify-html](https://github.com/wilsonzlin/minify-html)\n(which has a convenient [Python package](https://pypi.org/project/minify-html/)) for\ngeneral minification.\nIt is great and fast.\nBut I found I kept running into\n[issues](https://github.com/wilsonzlin/minify-html/issues/236) and in any case wanted\nproper Tailwind v4 compilation, so switched to this of combining Tailwind compilation\nwith robust HTML/CSS/JS minification.\n\n## Example Usage\n\nTake a file you want to minimize.\nLet’s put this file into `page.html`. Note we are using the Play CDN for simple\nzero-build development:\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n    \u003cmeta charset=\"UTF-8\"\u003e\n    \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"\u003e\n    \u003ctitle\u003eTest HTML\u003c/title\u003e\n    \u003cscript src=\"https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4\"\u003e\u003c/script\u003e\n    \u003cstyle\u003e\n        /* Custom CSS that will be minified alongside Tailwind */\n        .custom-shadow { \n            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); \n        }\n    \u003c/style\u003e\n\u003c/head\u003e\n\u003cbody class=\"m-0 p-5 bg-gray-50\"\u003e\n\u003cdiv class=\"custom-shadow bg-gray-100 p-4 m-2 rounded-lg\"\u003e\n  \u003ch1 class=\"text-2xl font-bold text-blue-600 mb-3\"\u003eTest Header\u003c/h1\u003e\n  \u003cp class=\"text-gray-700 mb-4\"\u003eThis is a test paragraph with some content.\u003c/p\u003e\n  \u003cbutton \n      onclick=\"testFunction()\" \n      class=\"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded transition-colors duration-200\"\u003e\n      Click Me\n  \u003c/button\u003e\n\u003c/div\u003e\n\u003cscript\u003e\n  // This JavaScript should get minified\n  function testFunction() {\n      console.log('Hello from test function!');\n      alert('Button was clicked!');\n      return 'Some return value';\n  }\n\u003c/script\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\nIf you want to minify it and compile all Tailwind CSS:\n\n```shell\n$ tminify page.html page.min.html --verbose\nTailwind v4 CDN script detected: will compile and inline Tailwind CSS\nFound 1 \u003cstyle\u003e tags in body size 1091 bytes, returning CSS of size 245 bytes\nTailwind input CSS:\n   @import \"tailwindcss\";\n   @source \"/Users/levy/wrk/github/tminify/page.html\";\n           /* Custom CSS that will be minified alongside Tailwind */\n           .custom-shadow { \n               box-shadow:…\nTailwind config: /Users/levy/wrk/github/tminify/tmp4g35wsgu/tailwind.config.js:\n   module.exports = {\n     \"content\": [\n       \"page.html\"\n     ],\n     \"corePlugins\": {\n       \"preflight\": false\n     },\n     \"theme\": {\n       \"extend\": {}\n     },\n     \"plugins\": []\n   };\nRunning: npx @tailwindcss/cli --input - --output /Users/levy/wrk/github/tminify/tmp4g35wsgu/tailwind.min.css --config /Users/levy/wrk/github/tminify/tmp4g35wsgu/tailwind.config.js --minify\nTailwind stderr: ≈ tailwindcss v4.1.8\n\nDone in 54ms\n\nTailwind CSS v4 compiled and inlined successfully\nMinifying HTML (including inline CSS and JS)...\nRunning: npx html-minifier-terser --collapse-whitespace --remove-comments --minify-css true --minify-js true -o /Users/levy/wrk/github/tminify/page.min.htmlk5geeie0v48wv.partial /Users/levy/wrk/github/tminify/page.mindwa99o7p.html\nHTML minified and written: page.min.html\nTailwind CSS compiled, HTML minified: 1091 bytes → 6893 bytes (+531.8%) in 1s\n\n$ cat page.min.html \n\u003c!DOCTYPE html\u003e\u003chtml\u003e\u003chead\u003e\u003cmeta charset=\"UTF-8\"\u003e\u003cmeta name=\"viewport\" content=\"width=device-width,initial-scale=1\"\u003e\u003ctitle\u003eTest HTML\u003c/title\u003e\u003cstyle\u003e/*! tailwindcss v4.1.8 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,::backdrop,:after,:before{--tw-font-weight:initial;--tw-duration:initial}}}@layer theme{:host,:root{--font-sans:ui-sans-serif,system-ui,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace;--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-700:oklch(37.3% .034 259.733);--color-white:#fff;--spacing:.25rem;--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--font-weight-bold:700;--radius-lg:.5rem … .custom-shadow{box-shadow:0 4px 8px #0000001a}@property --tw-font-weight{syntax:\"*\";inherits:false}@property --tw-duration{syntax:\"*\";inherits:false}\u003c/style\u003e\u003c/head\u003e\u003cbody class=\"m-0 p-5 bg-gray-50\"\u003e\u003cdiv class=\"custom-shadow bg-gray-100 p-4 m-2 rounded-lg\"\u003e\u003ch1 class=\"text-2xl font-bold text-blue-600 mb-3\"\u003eTest Header\u003c/h1\u003e\u003cp class=\"text-gray-700 mb-4\"\u003eThis is a test paragraph with some content.\u003c/p\u003e\u003cbutton onclick=\"testFunction()\" class=\"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded transition-colors duration-200\"\u003eClick Me\u003c/button\u003e\u003c/div\u003e\u003cscript\u003efunction testFunction(){return console.log(\"Hello from test function!\"),alert(\"Button was clicked!\"),\"Some return value\"}\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e…\n```\n\n(Last output truncated for clarity.)\n\nNote because of the Tailwind compilation this page actually grew because we’ve compiled\nin the CSS for instant loading (for large pages it is more likely to shrink).\n\n## Python Use\n\nAs a library: `uv add tminify` (or `pip install tminify` etc.). Then:\n\n```python\nfrom pathlib import Path\nfrom tminify import tminify\n\ntminify(Path(\"page.html\"), Path(\"page.min.html\"))\n```\n\n* * *\n\n## Project Docs\n\nFor how to install uv and Python, see [installation.md](installation.md).\n\nFor development workflows, see [development.md](development.md).\n\nFor instructions on publishing to PyPI, see [publishing.md](publishing.md).\n\n* * *\n\n*This project was built from\n[simple-modern-uv](https://github.com/jlevy/simple-modern-uv).*\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjlevy%2Ftminify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjlevy%2Ftminify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjlevy%2Ftminify/lists"}