{"id":18300415,"url":"https://github.com/jpdevries/developer-style-guide","last_synced_at":"2026-01-21T04:32:21.910Z","repository":{"id":140004999,"uuid":"95306288","full_name":"jpdevries/developer-style-guide","owner":"jpdevries","description":"Best practices when authoring the web (components)","archived":false,"fork":false,"pushed_at":"2017-06-30T00:46:28.000Z","size":268,"stargazers_count":3,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-09T09:37:40.320Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jpdevries.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}},"created_at":"2017-06-24T15:32:14.000Z","updated_at":"2021-06-25T19:43:11.000Z","dependencies_parsed_at":"2023-05-01T03:46:19.427Z","dependency_job_id":null,"html_url":"https://github.com/jpdevries/developer-style-guide","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jpdevries/developer-style-guide","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpdevries%2Fdeveloper-style-guide","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpdevries%2Fdeveloper-style-guide/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpdevries%2Fdeveloper-style-guide/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpdevries%2Fdeveloper-style-guide/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jpdevries","download_url":"https://codeload.github.com/jpdevries/developer-style-guide/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpdevries%2Fdeveloper-style-guide/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28626228,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-21T02:47:06.670Z","status":"ssl_error","status_checked_at":"2026-01-21T02:45:44.886Z","response_time":86,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":"2024-11-05T15:12:15.554Z","updated_at":"2026-01-21T04:32:21.896Z","avatar_url":"https://github.com/jpdevries.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# A Web Developer's Style Guide\n\n*As this guide was born from the [`modx-style-guide`](https://github.com/jpdevries/modx-style-guide) you'll find we note that parts of this style guide may apply to authoring web components, and not necessarily web\u0026nbsp;pages or\u0026nbsp;sites.*  \n\nHTML is initially performant, optimal, and accessible. So we recommend starting your components HTML\u0026ndash;first.\n\n## Authoring Markup\nSemantic HTML documents are implicitly performant, optimal, and accessible. So we recommend starting coding your component as such. If you need to post or get data to and from the database start with a semantic HTML form. JavaScript should always be used as an enhancement. As you progressively enhance your markup into a more asynchronous user experience ensure that you do not degrade the initial accessibility of your semantic\u0026nbsp;document. \n\n### Performant Markup\nTo evaluate the semantics of your HTML, test and view your HTML with CSS styles disabled. A semantic HTML document should remain usable in the nued. To keep the Manager experience reliable in the event of script breakages test your components with JavaScript\u0026nbsp;disabled.\n\n**See Also**\n\n - [There is no speed in Web Performance](https://medium.com/markuptips/there-is-no-speed-in-web-performance-1457f6ee79a3)\n\n## Authoring Styles\nWe recommend progressively enhancing CSS styles. For example, if you use modern grid layout enhance our layout from a block layout, to a flexible layout, and finally to a grid layout. You are free to use the same CSS preprocessor and postprocessor tooling found in the default theme. However you author your styles, please keep accessibility in mind. By using CSS Properties and `spectacular.scss` you'll ensure that your components automatically respond to users accessibility preferences such as high contrast\u0026nbsp;modes.\n\n### Scoped Styles\nGlobal style should be global, but components are another story. How you author your components styles is ultimately up to you, but they shouldn't class with other components. Avoid overriding base styles of the Manager theme. We recommended prefixing your CSS classes with an identifier unique to your component. For\u0026nbsp;example:\n\n**Do this:**\n```css\n.batcher table {\n  /* styles specific to the batcher component */\n}\n```\n\n**Don't do this:**\n```css\n.table {\n  /* dangerously loose styles */\n}\n```\n\n### Themable Styles with CSS Properties\nCSS Properties inhereted from the `.mx-component` class allow us to style various aspects of our component in one block without declaratively overriding them. Here we set a default color of blue, respond to active high contrast modes by setting the color to dark blue, and respond to black-on-white and white-on-black contrast preferences\u0026nbsp;accordingly.\n\n```css\n.mx-component.my-component {\n  /* layout */\n  --flex-grow: 1; /* grow horizontally on mobile */\n  --flex-shrink: 0; /* don't shrink */\n\n  --tablet-flex-grow: 0; /* don't grow horizontally on tablet and up */\n  --tablet-flex-basis: 42ch; /* set a flex basis on tablet and up */\n\n  /* base */\n  --color: blue;\n  --background: white;\n\n  --active-contrast-color: darkblue; /* triggered in ms-high-contrast: active mode */\n\n  /* .mx-component inherits black-on-white and white-on-black styles\n     automagically but here is an example how to customize them */\n  --black-on-white-background: white; /* triggered in ms-high-contrast: black-on-white mode */\n  --black-on-white-color: rgb(8, 8, 8); /* almost black, triggered in ms-high-contrast: black-on-white mode */\n\n  --white-on-black-color: white; /* almost black, triggered in ms-high-contrast: white-on-black mode */  \n  --white-on-black-background: rgb(8, 8, 8); /* almost black, triggered in ms-high-contrast: black-on-white mode */\n}\n```\n\n**See Also**\n - [Why I'm Excited About Native CSS Variables](https://philipwalton.com/articles/why-im-excited-about-native-css-variables/)\n\n### Responding to User Preferences\n\nThe `.my-component` class responds to most user preferences for you, but if you wish to customize or alter them you can override these properties. For contrast preferences use both media queries and the `data-` API like so:\n\n```css\n.mx-component.my-component {\n  /* triggered by system and user level settings */\n  [data-contrast=\"active\"] \u0026 {\n    .logo {\n      background-image: url('logo-high-contrast.svg');\n    }\n  }\n\n  /* triggered by user agent level settings */\n  @media screen and (-ms-high-contrast: active) {\n    .logo {\n      background-image: url('logo-high-contrast.svg');\n    }\n  }\n}\n```\n\n## Accessibility Guidelines\n\nFor an inclusive user experience, follow the latest accessibility guidelines. Incoporate accessibility as early on in your process as possible, ideally in the initial phase. Reach out the greater accessibility community with the [`#a11y` Twitter Hashtag](https://twitter.com/hashtag/a11y?lang=en) and the A11y [Slackers Slack Channel](https://www.paciellogroup.com/blog/2015/07/anybody-can-be-an-a11y-slacker/). Don't overwhelm yourself. In the words of\u0026nbsp;Léonie Watson:\n\n\u003e Accessibility doesn't have to be perfect. It just needs to be a little better than it was yesterday.  \n\u0026emsp;\u0026mdash;\u0026emsp;Léonie Watson, Technologic (Human Afterall): Accessibility mix, Fronteers\u0026nbsp;AMS\u0026nbsp;2016\n\nBy making each project a little more accessibile than the last, you and your team will be naturally architecting inclusive experience soon\u0026nbsp;enough.\n\n**See Also**\n\n - [RGD Accessibility Handbook](https://www.rgd.ca/resources/accessibility.php)\n\n## Accessibility Testing\n\nA significant portion of accessibiilty testing can be done using automation. We recommend testing your Extras with the `axe-core` Chrome extensions prior to manual\u0026nbsp;testing.\n\n**See Also**\n\n - [Accessibility Testing with aXe](http://marcysutton.github.io/a11y-testing-with-axe)\n \n\n\n\n## Cohesive User Experience\nTo keep the end user experience harmonious, keep in mind that less is more. Utilize CSS inheritance from the Manager theme's base styles to keep your component consistent with the theme it resides within. Things like colors, typography, hover effects and focus styles should ideally be consistent across the various components of any given\u0026nbsp;page.\n\n## Use Relative Units\nTo meet accessibility guidelines it is important that you use relative units for typography and layout. Do not use declarative units such as pixels to set type or define media queries as doing so is incompatible with text\u0026ndash;only zoom\u0026nbsp;features.\n\n**Do this:**\n\n```css\n.my-component {\n  /* use relative units for typography and layout */\n  font-size: 1.2rem;\n  padding: 1rem;\n  max-width: 42ch;\n}\n```\n\n**Don't do this:**\n\n```css\n.my-component {\n  font-size: 18px;\n  padding: 10px;\n  max-width: 400px;\n}\n```\n\n**See Also:**\n\n - [PX, EM or REM Media Queries?](https://zellwk.com/blog/media-query-units/)\n - [rems, ems and Why you Probably Need Them](https://medium.com/@jpdevries/rems-and-ems-and-why-you-probably-need-them-ff99a0002cdd)\n\n## Authoring Scripts\nWe recommend using a [webpack](https://webpack.js.org) workflow to preprocess and bundle modern JavaScript modules into production code that is delivered to the browser. Bundling modules allows for code reuse.\n\n### Everything in its Right Place\n\nWhen making JavaScript enhancements it is important that you only take over ownership of your component's area of the\u0026nbsp;DOM.\n\n**Do this:**\n```jsx\nconst myWrapper = document.getElementById(#my-component-wrapper');\nReactDOM.render(\u003cMyComponent /\u003e, myWrapper);\n```\n\n**Don't do this:**\n```jsx\nReactDOM.render(\u003cMyEverything /\u003e, document.body);\n```\n\n### Syntax Sugar\nWe recommend writing modern JavaScript with syntax sugar and running it through Babel to transpile it back to ES5 for production as/if\u0026nbsp;necessary. Feel free to take advantage of new syntax sugar like `const`, `let`, arrow functions, Promises, async/await and\u0026nbsp;more.\n\n**See Also**\n\n - [Babel](https://babeljs.io)\n\n## Asynchronous Requests\nAJAX requests use the Promise based Fetch API. For example we'd request a JSON response containing an array of all resources like\u0026nbsp;so:\n\n```js\nfetch(`/resources`, {\n  credentials: 'include'  \n}).then((resources) =\u003e {\n  resources.map((resource) =\u003e {\n    console.log(resource.pagetitle);\n  });\n});\n```\n\nFor security purposes it is important to include credentials with the request so that cookies can be sent and\u0026nbsp;received.\n\nYou'll likely need to `POST`, `PUT`, and `DELETE` data to your component's connectors. Set the method and body properties of the request options Object like\u0026nbsp;so:\n\n```js\nconst formData = new FormData(document.getElementById('resource-create'));\n\nfetch(`/resources`, {\n  method: 'PUT',\n  body: formData,\n  credentials: 'include'  \n}).then((resource) =\u003e {\n  console.log(`resource created with an id of ${resource.id}`)\n});\n```\n\nYou write fantastic code. But that doesn't mean it will always work. Handle errors by catching them like\u0026nbsp;so:\n\n```js\nfetch(`/resources`, {\n  //credentials: 'include' // whoops\n}).then((resources) =\u003e {\n  resources.map((resource) =\u003e {\n    console.log(resource.pagetitle);\n  });\n}).catch((err) =\u003e {\n  console.log('uh oh');\n  console.error(err);\n});\n```\n\n**See Also**\n\n - [Fetch API](https://developer.mozilla.org/en/docs/Web/API/Fetch_API)\n - [Promise API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)\n\n## Joining Paths\n\nTo ensure that paths don't break if the trailing slash are omitted we recommend using `path.join()` like\u0026nbsp;so:\n\n```js\nimport path from 'path';\n\nfetch(path.join(config.assetsURL, mycomponent))\n```\n\n**See Also**\n\n - [`path.join()`](https://nodejs.org/api/path.html#path_path_join_paths)\n\n## Code Splitting\n\nTo provide an optimal experience to all users, we recommend loading scripts only when and if they are needed. For example, imagine you have an image manager component that displays a grid of images and allows them to be cropped in a modal window. We don't want to load the cropping code until it is called upon. We can accomplish this using the modern Async/Await\u0026nbsp;pattern:\n\n```js\nexport default class ImageGrid extends Component {\n  async openModalWindow() {\n    const ImageCropper = await import('ImageCropper');\n  }\n}\n```\n\n**Examples**\n\n - [Lazy Load React Modal](https://jpdevries.github.io/lazy-react-modal/)\n\n## Leveraging Browser Cache\n\nTo effectively leverage the browser cache refrain from bundling common frameworks and libraires such as Angular, React, or jQuery with your code. Instead, load them as separate files like\u0026nbsp;so:\n\n```html\n\u003c!-- load jQuery separately --\u003e\n\u003cscript src=\"assets/js/vendor/jquery-3.2.0.min.js\"\u003e\u003c/script\u003e\n\u003c!-- load your component --\u003e\n\u003cscript src=\"assets/components/mycomponent/js/mycomponent.js\"\u003e\u003c/script\u003e\n```\n\n### CDN with local fallbacks\nTo leverage the browser cache we recommend loading common frameworks and libraries from a CDN with a local fallback like\u0026nbsp;so:\n\n```html\n\u003c!-- first attempt to load jQuery from a CDN --\u003e\n\u003cscript src=\"//code.jquery.com/jquery-3.2.0.min.js\" integrity=\"sha256-JAW99MJVpJBGcbzEuXk4Az05s/XyDdBomFqNlM3ic+I=\" crossorigin=\"anonymous\"\u003e\u003c/script\u003e\n\u003c!-- if the CDN didn't work load jQuery from a local fallback --\u003e\n\u003cscript\u003ewindow.jQuery || document.write('\u003cscript src=\"assets/js/vendor/jquery-3.2.0.min.js\"\u003e\u003c\\/script\u003e')\u003c/script\u003e\n\u003c!-- load your component --\u003e\n\u003cscript src=\"assets/components/mycomponent/js/mycomponent.js\"\u003e\u003c/script\u003e\n```\n\n### Reluctant Loading\nThere is no point in loading a common framework or library if a sufficient version of it is already loaded in the page. Before loading common dependencies perform feature detection to test if they are needed like\u0026nbsp;so:\n\n```html\n\u003c!-- check if we need jQuery, then if needed attempt to load jQuery from a CDN --\u003e\n\u003cscript\u003ewindow.jQuery || document.write('\u003cscript src=\"//code.jquery.com/jquery-3.2.0.min.js\" integrity=\"sha256-JAW99MJVpJBGcbzEuXk4Az05s/XyDdBomFqNlM3ic+I=\" crossorigin=\"anonymous\"\u003e\u003c\\/script\u003e')\u003c/script\u003e\n```\n\n### Cachebusting Assets\nTo leverage the browser cache and ensure that the cache is flushed when updates are made it is important to include a version number or some type of unique hash within your assets file name. For example instead of `app.js` you'd name your file\u0026nbsp;`app.1.0.0.js`.\n\n### Lazy Load Scripts\n\nThus far we've explored HTML patterns to load scripts. You can also load your depdencies with\u0026nbsp;`lazyload-script`:\n\n```js\nimport lazyLoadScript from 'lazyload-script';\n\nconst promises = [];\n\nif(!React) promises.push(\n  // try to load React from a CDN, fallback to a local copy\n  lazyLoadScript(\"https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.min.js\", \"react.15.4.2.min.js\").catch((err =\u003e (\n    lazyLoadScript(`./js/vendor/react.15.4.2.min.js`, \"react.15.4.2.min.js\")\n  )))\n);\n\nif(!ReactDOM) promises.push(\n  // try to load React DOM from a CDN, fallback to a local copy\n  lazyLoadScript(\"https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.min.js\", \"react-dom.15.4.2.min.js\").catch((err =\u003e {\n    lazyLoadScript(`./js/vendor/react-dom.15.4.2.min.js`, \"react-dom.15.4.2.min.js\")\n  }))\n);\n\nif(!Redux) promises.push(\n  // try to load Redux from a CDN, fallback to a local copy\n  lazyLoadScript(\"https://cdnjs.cloudflare.com/ajax/libs/redux/3.6.0/redux.min.js\", \"redux.3.6.0.min.js\").catch((err =\u003e {\n    lazyLoadScript(`./js/vendor/redux.3.6.0.min.js`, \"redux.3.6.0.min.js\")\n  }))\n);\n\nif(!ReactRedux) promises.push(\n  // try to load React Redux from a CDN, fallback to a local copy\n  lazyLoadScript(\"https://cdnjs.cloudflare.com/ajax/libs/react-redux/5.0.3/react-redux.min.js\", \"react-redux.5.0.3.min.js\").catch((err =\u003e {\n    lazyLoadScript(`./js/vendor/react-redux.5.0.3.min.js`, \"react-redux.5.0.3.min.js\")\n  }))\n);\n\nPromise.all(promises).then(() =\u003e {\n  // React, React DOM, Redux, and React Redux are ready. woohoo!\n});\n```\n\n**Examples**\n\n - [Makeanico](https://github.com/jpdevries/makeanico#weigh-in)\n\n**See Also**\n\n - [webpack Externals](https://webpack.js.org/configuration/externals/)\n - [`lazyload-script`](https://www.npmjs.com/package/lazyload-script)\n\n### Service Workers\n\nTo improve user experience and performance on subsequent visits to the Manger, we recommend that you include a Service Worker with your Extra that hard cache appropriate assets like versioned CSS and JavaScript\u0026nbsp;files.\n\n```js\nconst VERSION = '1.0.0-pl',\nSTICKY_FILES = [ // these files will be stored in the service worker cache\n  `css/my-component.${VERSION}.css`,\n  `css/my-component.${VERSION}.min.css`,\n  `img/my-component.${VERSION}.svg`,\n  `img/my-component.${VERSION}.min.svg`,\n  `js/my-component.${VERSION}.js`,\n  `js/my-component.${VERSION}.min.js`\n];\n\nself.addEventListener('install', function(event) {\n  self.skipWaiting(); // greedily install the service worker\n});\n\nfunction endsWithStickyFile(request) { // is the request to a sticky file?\n  for(let i = 0; i \u003c STICKY_FILES.length; i++) if(request.endsWith(STICKY_FILES[i])) return true;\n  return false;\n}\n\nself.addEventListener('fetch', function(event) {\n  if(event.request.method !== 'GET' || !endsWithStickyFile(event.request)) return;\n  event.respondWith(\n    caches.match(event.request).then(function(resp) {\n      return resp || fetch(event.request).then(function(response) {\n        return caches.open(CACHE_NAME).then(function(cache) {\n          cache.put(event.request, response.clone());\n          return response;\n        });\n      });\n    })\n  );\n});\n\nself.addEventListener('activate', function(event) {\n  var cacheWhitelist = [VERSION];\n\n  event.waitUntil(\n    caches.keys().then(function(keyList) { // purge old cache partitions\n      return Promise.all(keyList.map(function(key) {\n        if (!cacheWhitelist.includes(key)) return caches.delete(key);\n      }));\n    }).then(function() {\n      self.clients.claim()\n    })\n  );\n});\n```\n\nDon't forget to register your service worker.\n\n```js\n// Register the ServiceWorker\n  navigator.serviceWorker.register(`assets/components/my-component/service-worker.js`, {\n  scope: './'\n}).then(function(reg) {\n  // service worker is registered\n});\n```\n\n**See Also**\n\n - [Using Service Workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers)\n\n## Enhancing Forms\n\nWith a little creativity, just about any web component can be enhanced from a HTML form. Consider the following HTML\u0026nbsp;form:\n\n```html\n\u003cform id=\"signup\" action=\"/core/connectors/mycomponent/signup\" method=\"POST\"\u003e\n  \u003clabel for=\"email\"\u003e\n    Email\n    \u003cinput required type=\"email\" id=\"email\" name=\"email\" /\u003e\n  \u003c/label\u003e\n  \u003cbutton\u003eSign Up\u003c/button\u003e\n\u003c/form\u003e\n```\n\nWhen the form is submitted an email address will syncronously be posted to `/core/connectors/mycomponent/signup`. Now consider you want to enhance this form to be asyncronous. You may be tempted to do something like the\u0026nbsp;following:\n\n```js\nconst signup = document.getElementById(\"signup\");\nsignup.querySelector('button').addEventListener('click', (event) =\u003e {\n  event.preventDefault();\n\n  const email = document.getElementById(\"email\");\n  // send the email to the server\n});\n```\n\nThere are several issues here:\n - not all users click\n - we are bypassing the HTML5 Form Validation API\n - we are unnecessarily querying the DOM for the input value\n\n Instead of listening to a click event on the submit button, listen to the submit event on the\u0026nbsp;form:\n\n ```js\ndocument.getElementById(\"signup\").addEventListener('submit', (event) =\u003e {\n  event.preventDefault();\n\n  const formData = new FormData(event.target),\n  email = formData.get(\"email\");\n  // send the email to the server\n});\n```\n\n**See Also**\n\n - [Give your Forms some Form](https://medium.com/front-end-hacking/give-your-forms-some-form-2ec73cb36981)\n\n## Meaningful Placeholder Text\n\nThe HTML5 placeholder attribute is meant to offer a suggestion of a valid entry, not to label an\u0026nbsp;input.\n\n**Do this:**\n\n```html\n\u003clabel for=\"pagetitle\"\u003ePage Title\u003c/label\u003e\n\u003cinput id=\"pagetitle\" name=\"pagetitle\" type=\"text\" placeholder=\"MODX rules\" /\u003e\n```\n\n**Don't do this:**\n\n```html\n\u003cinput id=\"pagetitle\" name=\"pagetitle\" type=\"text\" placeholder=\"Page title\" /\u003e\n```\n\n**See Also**\n - [11 reasons why placeholders are problematic](https://medium.com/simple-human/10-reasons-why-placeholders-are-problematic-f8079412b960)\n - [Meaningful Placeholder Attributes](https://medium.com/front-end-hacking/give-your-forms-some-form-2ec73cb36981#57c2)\n - [Visually Hiding Form Labels](https://medium.com/front-end-hacking/give-your-forms-some-form-2ec73cb36981#fa3d)\n\n## Formatting Dates and Times\n\nBy using the `Date.toLocaleString()`, `Date.date.toLocaleDateString()`, and `Date.prototype.toLocaleTimeString()` when formatting dates they'll always be formatted in the expected local format based on the user agent. For\u0026nbsp;example:\n\n```js\nconst dateTimeString = new Date().toLocaleString(),\ndateString = new Date().toLocaleDateString(),\ntimeString = new Date().toLocaleTimeString();\n```\n\n**See Also**\n\n - [`Date.toLocaleString()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjpdevries%2Fdeveloper-style-guide","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjpdevries%2Fdeveloper-style-guide","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjpdevries%2Fdeveloper-style-guide/lists"}