{"id":15130433,"url":"https://github.com/madebywild/wildplate","last_synced_at":"2025-09-28T20:30:20.285Z","repository":{"id":85026880,"uuid":"79169543","full_name":"madebywild/wildplate","owner":"madebywild","description":"An opinionated, modern post-gulp-era toolkit tailored for visual-heavy microsites and less for data-driven apps.","archived":true,"fork":false,"pushed_at":"2017-03-27T13:02:52.000Z","size":135,"stargazers_count":1,"open_issues_count":3,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-01-15T17:23:06.471Z","etag":null,"topics":["boilerplate","css-modules","imagemin","microsite","postcss","react","scss","toolkit","webpack2"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/madebywild.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2017-01-16T23:39:49.000Z","updated_at":"2023-01-28T07:11:10.000Z","dependencies_parsed_at":"2023-09-18T07:15:15.857Z","dependency_job_id":null,"html_url":"https://github.com/madebywild/wildplate","commit_stats":{"total_commits":35,"total_committers":1,"mean_commits":35.0,"dds":0.0,"last_synced_commit":"9e71a49f0ebd04e613e2a00cd975842ad7a28fb4"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madebywild%2Fwildplate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madebywild%2Fwildplate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madebywild%2Fwildplate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madebywild%2Fwildplate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/madebywild","download_url":"https://codeload.github.com/madebywild/wildplate/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234556139,"owners_count":18851912,"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","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":["boilerplate","css-modules","imagemin","microsite","postcss","react","scss","toolkit","webpack2"],"created_at":"2024-09-26T02:47:16.902Z","updated_at":"2025-09-28T20:30:19.656Z","avatar_url":"https://github.com/madebywild.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/madebywild/wildplate\"\u003e\n    \u003cimg alt=\"wildplate\" src=\"https://raw.githubusercontent.com/madebywild/wildplate/master/logo.png\" width=\"600\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  An opinionated, modern post-gulp-era toolkit tailored for visual-heavy microsites and less for data-driven apps.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://twitter.com/madebywild\"\u003e\n    \u003cimg alt=\"@madebywild\" src=\"https://img.shields.io/twitter/follow/madebywild.svg?style=social\u0026label=Follow\u0026style=plastic\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\nBasically it leaves the gulp legacy behind and translates proven concepts to the webpack-era. To note here again: The goal is to be super easy to start while still being flexible, very asset-heavy and not really focused on data. If you want to create a rock-solid data-driven SPA, we suggest you to check out the [React Boilerplate](https://github.com/mxstbr/react-boilerplate) by our homie [Max Stoiber](https://github.com/mxstbr).\n\nSome feats:\n- [X] Future JS transpilation including async/await and ES7 static class properties\n- [X] Hot Reloading\n- [X] SCSS Modules\n- [X] Pre-Rendering as compilation step for SEO/Sharing visibility of static site without server\n- [X] Image Minification on the fly\n- [X] Automated Favicon generation\n- [X] Shader loading\n- [X] JS/SCSS shared variables\n- [X] Full Asset Revisioning upon change\n\n***\n\n## Install\n\nInstall the wildplate toolkit once globally (to make use of the CLI) with the package management tool of your choice.\n\n```bash\n$ npm install -g wildplate\n# or\n$ yarn global add wildplate\n```\n\nThen use it's install script in the working directory of your project. In most cases you should do this at the very beginning of your project, because this script will overwrite the versions of potentially already used modules in the `devDependencies` and `dependencies` sections in your `package.json`. So if you're integrating it into an old project, always make a backup of your `package.json`.\n\n```bash\n$ wildplate install\n```\n\nAfterwards you might want to spit out some boilerplate files for your app, but actually this step is optional.\n\n```bash\n$ wildplate init\n```\n\nWhat you might want to do in both cases is changing some configuration options in the `wildplate.js` file that has been created in the root directory of your project.\n\n## Update\n\nUpdating seems super easy (`npm update -g wildplate`), but in reality the most reliable way is simply to uninstall and re-install `wildplate`.\n\n```bash\n$ npm uninstall -g wildplate\n$ npm install -g wildplate\n```\n\n## Develop\n\nRun this dev command to start the development environment with hot module reloading (including the style).\n\n```bash\n$ wildplate start\n```\n\n## Build\n\nTo build for deployment simply run the following, it will bundle and build everything into the `build` directory or according to the settings in the `wildplate.js` file.\n\n```bash\n$ wildplate build\n```\n\n## Running in production\n\nFor your convenience there's a simple express-server to serve your application built in. Make sure you deploy the build directory, the root package.json, the wildplate directory and make sure you install the npm dependencies on the prodution server. Then you'll able to simply run:\n\n```bash\n$ wildplate start production\n```\n\n***\n\n## Configuration\n\nBuilding microsites is never following rigid rules. So that you don't have to fuss around with the actual config files, there is one `wildplate.js`-file in your root directory which you can set the most common wishes more easily. You'll find explanations of the options throughout this readme file and actual comments within the file.\n\n## HTML\n\nDuring compilation we use `app/index.html` (or whatever you specified in the config) as the template for our index file, we then automatically inject all assets, styles and scripts as they are used. If you need some external stuff (like a Typekit or Google Analytics Snippet), just throw it into your html-template.\n\nIn the `wildplate.js` file you have the option to make wildplate render your app and write the rendered version into the built index.html file. This is useful for using `React Helmet` for writing your `\u003chead\u003e` statements but still showing them on first load for eg. social sharing or SEO purposes. You can optionally define an event you manually fire when the site has completely load to ensure correct rendering. If you name your event 'post-render':\n\n```javascript\ndocument.addEventListener('DOMContentLoaded', function () {\n  render();\n  document.dispatchEvent(new Event('post-render'));\n});\n```\n\nFor every route you specify, a `index.html` file will be created in your outputPath. eg. \"/\": build/index.html, \"/about\": build/about/index.html.\n\n## Javascript\n\nAll sources are compiled, so go ahead and use all that `async/await` goodness. The entry point lives in `/app/app.js` (overrideable in the config), make sure to import everything you need in there! We'll transpile the code and errors don't exit the process [when encountering an error](https://github.com/webpack/docs/wiki/list-of-plugins#noerrorsplugin). All occurences of `process.env.NODE_ENV` are also replaced by the actual env-setting.\n\nWhen importing `.json`-files you automatically [get an object](https://github.com/webpack/json-loader). Don't worry about requiring the same module over and over again, during compilation we dedupe modules anyway.\n\nIf you use any 3rd party libraries which can't or won't be properly built with webpack, hit up the \"externals\" array with the module name in the javascript attribute in `wildplate.js`. For example:\n\n```js\nexternals: ['bootstrap']\n```\n\n## Images\n\nWhenever you need a static image (JP(E)G, PNG, GIF and SVG), import the image within the .js file where you want to use it first (this returns a path to the optimized image) and use it in your JS(X). The image will automatically be optimized (lossy, but super tiny) during building, you don't have to provide optimized images. Through requiring all assets we can name them with a hash, which aids long-term caching and makes sure when we deploy the client sees the new assets (because of the new filename).\n\n```javascript\nimport logo from '../logo_small.png'; // yields path to the image\n\u003cimg src={logo} /\u003e\n```\n\nOne special difference are SVG images. In 99% of the cases you want the flexibility of inlined SVGs (especially for animation). Import them regularly and use `svg-inline-react` for \"mounting\" it into JSX.\n\n```javascript\nimport InlineSVG from 'svg-inline-react';\nimport logo from '../logo.svg';\n\u003cInlineSVG src={logo} /\u003e\n```\n\nIn the unlikely case you need it to behave like other images inside an image tag, you can still do it, albeit you have to rename the SVG to end with an `.img.svg` extension (the actual file needs to have that extension, not only the import):\n\n```javascript\nimport logo from '../logo.img.svg';\n\u003cimg src={logo} /\u003e\n```\n\n## Audio \u0026 Video\n\nAudio and video files work exactly the same way that images work, but are not optimized. Instead, audio and video files that are smaller than 10000 bytes are inlined as data-url instead of copied to the build directory, all others are copied and the respective path yielded.\n\n```javascript\nimport video from '../video_compressed.mp4'; // yields path to the video\n\u003cvideo src={video}\u003e\u003c/video\u003e\n```\n\n## Fonts\n\nUsing external font services like Typekit or Typography.com obviously is a no-brainer. Using locally hosted files is now too. To use font files, simply write your regular font-face declarations with relative paths (make sure the actual .woff/.woff2/.eot/.otf files have the same filename without extension) to the font-files using this syntax:\n\n```scss\n@font-face {\n  font-family: 'Name You Use Later';\n  font-path: './yourFontDir/fontNameWithoutExtension';\n  font-weight: normal;\n  font-style: normal;\n}\n```\n\n## Shaders\n\nYou can import shaders as `.glsl` files just like any other source:\n\n```javascript\nvar shader = require('../glsl/fragment.glsl');\n```\n\nNote that inside your shaders you can import other shaders with a SCSS-like syntax:\n\n```scss\n@import ./includes/perlin-noise;\n```\n\n## Favicons\n\nFavicons are automatically generated and injected along with their manifest information from `app/favicon.png` or whatever you specified in the config. So naturally try to make sure that png-file is bigger than the biggest favicon. Nifty!\n\n## JS / SCSS Variables\n\nWith the out-of-the-box configuration (you can change this in the config under `variableFilePath`) the `app/vars.js` file exports an object with keys:\n\n```javascript\nmodule.exports = {\n  black: \"#000\",\n  blue: \"blue\"\n};\n```\n\nThese centralized variables can be imported regularly by importing the js file wherever you need it, but most importantly are available automagically in your `.scss` files as well!\n\nNote that at the moment you always have to restart the `wildplate start` dev process after editing the vars file, we'll work on removing that restriction.\n\n## Static Files\n\nIf you have a bunch of static files (like google site verification, sitemap.xml etc.) you can make use of the copying feature by enabling it in your `wildplate.js` config file. Simply set `assets.copyStatic` to `true` and optionally provide a custom source path, otherwise it picks up files at `app/static` and copies them to the output directory.\n\n## Styling\n\n### CSS Modules\n\nThis boilerplate out of the box is configured to use [css-modules](https://github.com/css-modules/css-modules). This allows you to use class names without having to worry about having used a particular name somewhere else in the project, since they get local scoped.\n\n```scss\n// Home.scss\n.hello {\n  color: blue;\n}\n```\n\n```javascript\n// Home.js\nimport styles from './Home.scss';\n\u003cdiv className={styles.hello}\u003eHello World!\u003c/div\u003e // actual class will be something like: Home__hello___2iVKA\n```\n\nAll `.scss` file extensions will use css-modules unless it has `.global.scss`. If you need global styles, stylesheets with `.global.scss` will not go through the css-modules loader. e.g. `app.global.scss`. This is especially useful for backwards compatibility, but don't forget to import them somewhere in your code!\n\nIf you want to centralize things like variables or mixins, simply create a `.scss` file and import it inside other `.scss` files with the familiar syntax. This has the benefit that other developers see what is being imported and can figure out more easily where a certain variable or mixin is coming from.\n\nAll `.css` files are simply included in the build without any transformation to ensure compatibility with styles from externals modules.\n\n### New Features\n\nThanks to Post-CSS we have some new tools to work with. You don't have to configure anything to use them. But at the same time you don't have to use them at all!\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eTypography\u003c/strong\u003e\u003c/summary\u003e\n\nWe'll automatically convert the fonts to data-urls and inject them into the css to save http requests and make things less complicated. Note that this could in some cases lead to issues in IE8, but who cares nowadays.\n\nCreate automagical fluid typography with a new responsive property on font-size. All values can be in `px`, `rem`, or `em`.\n\n```scss\nfont-size: responsive [min-font-size] [max-font-size]\nfont-range: [lower-bound] [upper-bound]\nhtml {\n  font-size: responsive 12px 21px;\n  font-range: 420px 1280px;\n}\n```\n\nCreate a custom vertical rhythm unit from the base font-size and line-height. Set the font on the body selector using the CSS shorthand method, you can use either px, em, rem or % unit for font-size:\n\n```scss\nbody {\n  font: 16px/2 serif;\n}\n```\nThis will create a line-height of 32px, which will be the vertical rhythm value. Now you can use the custom vertical rhythm unit, vr:\n```scss\n// Input:\np {\n  margin-bottom: 1vr;\n  padding-top: .5vr;\n}\n// Output:\np {\n  margin-bottom: 32px;\n  padding-top: 16px;\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eQuantity Pseudo-Selectors\u003c/strong\u003e\u003c/summary\u003e\n\nSelect and style elements based on their quantity.\n\n```scss\n// Applies if there are a certain number of items or more\nli:at-least(4) {\n  color: blue;\n}\n// Applies if there are a certain number of items or less\nli:at-most(4) {\n  color: blue;\n}\n// Applies to all items between a certain range\nli:between(4, 6) {\n  color: blue;\n}\n// Applies when there are exactly a number of items\nli:exactly(4) {\n  color: blue;\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eCross-Browser Input Pseudo-Elements\u003c/strong\u003e\u003c/summary\u003e\n\nStyle placeholders with the `::placeholder` pseudo-element. It can be applied to any input element, or at the root of your stylesheet for global styling. Style the notoriously tricky range input with `::track` and `::thumb`. Track targets the ‘line’, while thumb targets the ‘button’. They can be applied to any range element, or at the root of your stylesheet for global styling. The -webkit-appearance: none; and -moz-appearance: none; declarations are added to relevant elements so that your custom styles are properly applied. Note that this means that for webkit (Chrome, etc) you must style both ::track and ::thumb, since the appearance must be set on the root element.\n\n```scss\ninput::placeholder {\n  color: black;\n  opacity: 0.8;\n}\ninput[type=\"range\"]::track {\n  background: #9d9d9d;\n  height: 3px;\n}\ninput[type=\"range\"]::thumb {\n  background: #4286be;\n  width: 16px;\n  height: 8px;\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eClearfix\u003c/strong\u003e\u003c/summary\u003e\n\nA ‘clearfix’ is a method of making a parent element self-clear it’s children, so floats are contained. Two new methods are added, fix and fix-legacy. Both achieve the same outcome, with different levels of browser support. fix outputs cleaner code and is all that is needed for IE8+, fix-legacy support IE6/7.\n\n```scss\n.foo {\n  clear: fix;\n}\n.bar {\n  clear: fix-legacy;\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eProper Easings\u003c/strong\u003e\u003c/summary\u003e\n\nThe new easings are translated to cubic-bezier() functions on output that CSS can natively understand. You can use: `ease-in-sine, ease-out-sine, ease-in-out-sine, ease-in-quad, ease-out-quad, ease-in-out-quad, ease-in-cubic, ease-out-cubic, ease-in-out-cubic, ease-in-quart, ease-out-quart, ease-in-out-quart, ease-in-quint, ease-out-quint, ease-in-out-quint, ease-in-expo, ease-out-expo, ease-in-out-expo, ease-in-circ, ease-out-circ, ease-in-out-circ, ease-in-back, ease-out-back, ease-in-out-back`\n\n```scss\n.foo {\n  transition: all 250ms ease-in-cubic;\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eMedia Queries\u003c/strong\u003e\u003c/summary\u003e\n\nYou can write custom media queries!\n\n```scss\n@custom-media --small-viewport (max-width: 30em);\n@media (--small-viewport) {\n  /* styles for small viewport */\n}\n```\nyou will get:\n```scss\n@media (max-width: 30em) {\n  /* styles for small viewport */\n}\n```\n\nAlso you can use operators to define media queries, which is easier to remember.\n\n```scss\n@media screen and (width \u003e= 500px) and (width \u003c= 1200px) {\n  .bar {\n    display: block;\n  }\n}\n```\nYou will get:\n```scss\n@media screen and (min-width: 500px) and (max-width: 1200px) {\n  .bar {\n    display: block;\n  }\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eCustom selectors\u003c/strong\u003e\u003c/summary\u003e\n\nYou can go overboard and invent new custom selectors which might aid development speed in some cases.\n\n```scss\n@custom-selector :--heading h1, h2, h3, h4, h5, h6;\narticle :--heading + p {\n  margin-top: 0;\n}\n```\nYou will get:\n```scss\narticle h1 + p,\narticle h2 + p,\narticle h3 + p,\narticle h4 + p,\narticle h5 + p,\narticle h6 + p {\n  margin-top: 0;\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eOld Browsers\u003c/strong\u003e\u003c/summary\u003e\n\n[Autoprefixer](https://github.com/postcss/autoprefixer) is on-board automatically, nothing to prefix for you. Also we [take care](https://github.com/seaneking/laggard) of older browsers by converting modern standards to things older browsers understand.\n\nIf you have to go further and have to support something like IE8, you might want to look at integrating [oldie](https://github.com/jonathantneal/oldie) to generate a second stylesheet just for those browsers ans use conditional includes. Because that shouldn't really happen anymore nowadays, this feature is not built-in.\n\n\u003c/details\u003e\n\n## Other files\n\nIf you have other files like let's say a `.htaccess`, simply require them somewhere with the following syntax in your code (preferably sooner than later) to let them be copied to the build folder:\n\n```javascript\n// file-loader ? name=the-destination-path ! the-source-path\nrequire(\"file-loader?name=[name].[ext]!./app/.htaccess\");\n```\n\n***\n\n## FAQ\n\n### Why don't you use the DLL plugin?\nWhile it does bring performance benefits during development, it complicates tooling by a huge margin and requires ugly hacks to work properly along other features. We might add it later.\n\n### Why is install a seperate command?\nThis has defensive reasons. Imagine you install `wildplate` into an existing project and it does all kinds of nasty things to existing code. We think you should be in control of what is happening. If we find out that it'd be useful, we might add it later.\n\n### When I try to import my images, I get an error: “ Library not loaded: /usr/local/opt/libpng/lib/libpng16.16.dylib”\nSometimes you need to install `libpng` first on OSX:\n```bash\n# Install homebrew if you didn't already:\n/usr/bin/ruby -e \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)\"\n# Install libpng\nbrew install libpng\n```\n\n## License\nMIT © [Thomas Strobl](https://github.com/tom2strobl)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmadebywild%2Fwildplate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmadebywild%2Fwildplate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmadebywild%2Fwildplate/lists"}