{"id":18318891,"url":"https://github.com/axept/javascript","last_synced_at":"2026-05-06T22:02:01.067Z","repository":{"id":57152428,"uuid":"84609666","full_name":"axept/javascript","owner":"axept","description":"JavaScript Style Guide","archived":false,"fork":false,"pushed_at":"2018-02-20T16:17:26.000Z","size":54,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-03T06:48:30.313Z","etag":null,"topics":["arrow-functions","code-style","codestyle","es6","eslint","javascript","linting","naming-conventions","prettier","style-guide","styleguide"],"latest_commit_sha":null,"homepage":"","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/axept.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}},"created_at":"2017-03-10T23:37:12.000Z","updated_at":"2017-09-08T14:17:18.000Z","dependencies_parsed_at":"2022-08-27T16:52:12.268Z","dependency_job_id":null,"html_url":"https://github.com/axept/javascript","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/axept%2Fjavascript","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/axept%2Fjavascript/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/axept%2Fjavascript/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/axept%2Fjavascript/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/axept","download_url":"https://codeload.github.com/axept/javascript/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248054196,"owners_count":21039952,"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":["arrow-functions","code-style","codestyle","es6","eslint","javascript","linting","naming-conventions","prettier","style-guide","styleguide"],"created_at":"2024-11-05T18:11:51.616Z","updated_at":"2026-05-06T22:02:00.552Z","avatar_url":"https://github.com/axept.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Axept JavaScript Style Guide\n\nFollow the original [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript).\n\nThis document describes only those rules which we decided to extend, to override or to add.\n\nOther Style Guides:\n\n+ [React](https://github.com/axept/javascript/tree/master/react)\n\nTODO:\n\n+ [ ] Make it as a shareable cards (Twitter, FB and other Social Media)\n+ [ ] Apply https://google.github.io/styleguide/javascriptguide.xml\n\n## Contents\n\n  1. [Comparison Operators \u0026 Equality](#comparison-operators--equality)\n  2. [Comments](#comments)\n  3. [Semicolons](#semicolons)\n  4. [Lines](#lines)\n  5. [Naming Conventions](#naming-conventions)\n  6. [Imports](#imports)\n  7. [Packages](#packages)\n  8. [Type Casting \u0026 Coercion](#type-casting--coercion)\n  9. [Template Strings](#template-strings)\n  10. [Objects](#object)\n  11. [Classes \u0026 Constructors](#classes--constructors)\n  12. [Unsorted Yet](#unsorted-yet)\n\n## Comparison Operators \u0026 Equality\n\nExtends: [Section 15](https://github.com/airbnb/javascript#comparison-operators--equality)\n\n  \u003ca name=\"comparison--no-ternary-in-expression\"\u003e\u003c/a\u003e\n  - [1.1](#comparison--no-ternary-in-expression) Ternaries should not be as a part of expression, only whole expression.\n    \u003e TODO: find or make ESLint rule for this\n\n    \u003e Why? The following example demonstrate how it could be misunderstood.\n  \n    ```javascript\n    // bad\n    const query = { 'forward_url': '/' }\n    const targetURL = 'https://qwe.com/auth?' + (typeof query === 'string') ? query : JSON.stringify(query)\n  \n    // Uncaught TypeError: split is not a function\n    // because type of targetURL is Object\n    const partsOfURL = targetURL.split('?')\n  \n  \n    // may be\n    const query = { 'forward_url': '/' }\n    const queryString = typeof query === 'string' ? query : JSON.stringify(query)\n    const targetURL = 'https://qwe.com/auth?' + queryString\n  \n  \n    // good\n    const query = { 'forward_url': '/' }\n    const queryString = (typeof query === 'string') ? query : JSON.stringify(query)\n    const targetURL = 'https://qwe.com/auth?' + queryString\n    ```\n\n**[⬆ back to top](#contents)**\n\n## Comments\n\nExtends: [Section 18](https://github.com/airbnb/javascript#comments)\n\n  \u003ca name=\"comments--no-obvious-comments\"\u003e\u003c/a\u003e\n  - [2.1](#comments--no-obvious-comments) Avoid using obvious comments.\n\n    \u003e Why? It makes code harder to read because you can think that here is something else than you see.\n  \n    ```javascript\n    // bad - it duplicates the function name\n  \n    /**\n     * Update hosts\n     */\n    function updateHosts(list) {\n      hosts = list\n    }\n  \n  \n    // good - nothing bad is better than something bad\n    function updateHosts(list) {\n      hosts = list\n    }\n  \n  \n    // bad - it duplicates the module path\n    import Drawer from 'react-native-drawer'\n  \n    // Components\n    import DrawerMenu from './components/drawer-menu'\n  \n  \n    // good - see the previous \"good\" explaination\n    import Drawer from 'react-native-drawer'\n    import DrawerMenu from './components/drawer-menu'\n  \n  \n    // good\n    if (!root.isAbstract()) {\n      // No need to wrap child nodes of a known concrete type.\n      return nextChildren;\n    }\n    ```\n\n**[⬆ back to top](#contents)**\n\n## Semicolons\n\nExtends: [Section 21](https://github.com/airbnb/javascript#semicolons)\n\n  \u003ca name=\"semicolons--nope\"\u003e\u003c/a\u003e\n  - [3.1](#semicolons--nope) Don't use semicolons, in the presence of excellent automation tools.\n    \u003e ESLint rule: [semi](http://eslint.org/docs/rules/semi)\n  \n    \u003e Why? Since we always have linting tools we can detect dangerous situations automatically. But this style makes us really faster according to a few years experience.\n\n**[⬆ back to top](#contents)**\n\n## Lines\n\n  \u003ca name=\"lines--width\"\u003e\u003c/a\u003e\n  - [4.1](#lines--width) 80 characters is good. But feel free to use up to 100 characters in a line.\n    \u003e ESLint rule: [max-len](http://eslint.org/docs/rules/max-len)\n  \n    \u003e Why? Almost all developers used to 80 characters. It's a very old practice. Now we have a wide screens and we used to seat a little bit more far from monitor. In this case we can use a bit more characters and code will be still readable.\n\n    Read [this](http://softwareengineering.stackexchange.com/questions/312889/how-to-follow-the-80-character-limit-best-practice-while-writing-source-code) and [this](http://stackoverflow.com/questions/578059/studies-on-optimal-code-width) for more details.\n  \n    ```javascript\n    // bad\n    if ((this.props.suggestions.length === 0) \u0026\u0026 (newProps.suggestions.length \u003e 0) \u0026\u0026 (newProps.autosuggestValue.length \u003e 0) {\n  \n      return\n    }\n  \n    // good\n    const hasSuggestions = (this.props.suggestions.length === 0)\n    const willHaveSuggestions = (newProps.suggestions.length \u003e 0)\n    if (hasSuggestions \u0026\u0026 willHaveSuggestions \u0026\u0026 (newProps.autosuggestValue.length \u003e 0)) {\n      return\n    }\n  \n    // good\n    const hasSuggestions = (this.props.suggestions.length === 0)\n    const willHaveSuggestions = (newProps.suggestions.length \u003e 0)\n    const willHaveAutosuggest = (newProps.autosuggestValue.length \u003e 0)\n    if (hasSuggestions \u0026\u0026 willHaveSuggestions \u0026\u0026 willHaveAutosuggest) {\n      return\n    }\n    ```\n  \n  \u003ca name=\"lines--excess-line\"\u003e\u003c/a\u003e  \n  - [4.2](#lines--excess-line) Don't use excess empty line\n     \u003e ESLint rule: [no-unexpected-multiline](http://eslint.org/docs/rules/no-unexpected-multiline), [padded-blocks](http://eslint.org/docs/rules/padded-blocks)\n    \n    ```javascript\n    // bad\n    const config = loadConfig()\n    \n    if (config) {\n      applyConfig(config)\n    }\n    \n    \n    // good\n    const config = loadConfig()\n    if (config) {\n      applyConfig(config)\n    }\n    ```\n  \n  \u003ca name=\"lines--function-declaration\"\u003e\u003c/a\u003e  \n  - [4.3](#lines--function-declaration) One empty line before and after function or class declaration.\n    \u003e ESLint rule: [no-unexpected-multiline](http://eslint.org/docs/rules/no-unexpected-multiline)\n    \n    \u003e Why? No empty line needed after function or class declaration - if the following line is javascript brackets.\n    \n    ```javascript\n    // bad\n    \n    const x = 0\n    function a() {\n      return 1\n    }\n    const b = () =\u003e 2\n    \n    \n    // bad\n    \n    const x = 0\n    class A {\n      a() {\n        return 1\n      }\n      b() {\n        return 2\n      }\n    }\n    \n    \n    // good\n    \n    const x = 0\n    \n    function a() {\n      return 1\n    }\n    \n    const b = () =\u003e 2\n    \n    \n    // good\n    \n    const x = 0\n    \n    class A {\n    \n      a() {\n        return 1\n      }\n    \n      b() {\n        return 2\n      }\n    }\n    ```\n\n**[⬆ back to top](#contents)**\n\n## Naming Conventions\n\nExtends: [Section 22](https://github.com/airbnb/javascript#naming-conventions)\n\n  \u003ca name=\"naming--no-reduced-names\"\u003e\u003c/a\u003e\n  - [5.1](#naming--no-reduced-names) Avoid using reduced names.\n\n    \u003e Why? It makes code harder to understand. Names are for readability, not to appease a computer algorithm.\n  \n    ```javascript\n    // bad - what does it mean \"ref\"? referals? references? single reference?\n    const ref1 = fetch('/api/books')\n  \n  \n    // good\n    const reference1 = fetch('/api/books')\n    ```\n  \u003ca name=\"naming--do-not-override-globals\"\u003e\u003c/a\u003e\n  - [5.2](#naming--do-not-override-globals) Do not override globals.\n\n    ```javascript\n    // bad \n    import fetch from './fetch-with-credentials'\n  \n    // good\n    import fetchWithCredentials from './fetch-with-credentials'\n  \n    // bad\n    function alert(message) {\n      console.error(message)\n    }\n  \n    // good\n    function alertToConsole(message) {\n      console.error(message)\n    }\n    ```\n\n  \u003ca name=\"naming--acronyms-and-initialisms\"\u003e\u003c/a\u003e\n  - [5.3](#naming--acronyms-and-initialisms) Acronyms and initialisms should always be all capitalized.\n  \n    \u003e Why? Names are for readability, not to appease a computer algorithm.\n  \n    ```javascript\n    // bad\n    import SmsContainer from './containers/SmsContainer'\n  \n    // bad\n    const HttpRequests = [\n      // ...\n    ]\n  \n    // good\n    import SMSContainer from './containers/SMSContainer'\n  \n    // good\n    const HTTPRequests = [\n      // ...\n    ]\n  \n    // best\n    import TextMessageContainer from './containers/TextMessageContainer'\n  \n    // best\n    const requests = [\n      // ...\n    ]\n    ```\n  \n**[⬆ back to top](#contents)**\n\n## Imports\n\n  \u003ca name=\"imports--order\"\u003e\u003c/a\u003e\n  - [6.1](#imports--order) Use the following modules import order:\n\n    + React\n    + Relay\n    + Redux\n    + Tools from node_modules\n    + Tools from current repo\n    + Other components\n    + Any kind of static assets\n    + Styles\n    + Constants\n\n**[⬆ back to top](#contents)**\n\n## Packages\n\n  \u003ca name=\"packages--lodash-and-ramda\"\u003e\u003c/a\u003e\n  - [7.1](#packages--lodash-and-ramda) Try to avoid using Lodash and Ramda.\n\n    \u003e Why? Underscore and Lodash has been made when ES6 has not been so popular. Ramda do not have performance benefits, but being opinionated custom approach increase unnecessary requirements for Developers skills. Besides of that Ramda did not stay \"standard de-facto\".\n\n**[⬆ back to top](#contents)**\n\n## Type Casting \u0026 Coercion\n\nExtends: [Section 22](https://github.com/airbnb/javascript#type-casting--coercion)\n  \n  \u003ca name=\"coercion--implicit-coercion\"\u003e\u003c/a\u003e\n  - [8.1](#coercion--implicit-coercion) Do not use JavaScript \"magic\".\n    \u003e ESLint rule: [no-implicit-coercion](http://eslint.org/docs/rules/no-implicit-coercion), [no-bitwise](http://eslint.org/docs/rules/no-bitwise)\n  \n    \u003e It makes source code more portable to other languages and available for reading by other developers.\n\n    ```js\n    // bad\n    const b = !!a\n    \n    // bad\n    const b = (~a.indexOf('k'))\n    \n    // bad\n    const c = !!d.length\n    \n    // good\n    const b = Boolean(a)\n    \n    // good\n    const b = (a.indexOf('k') \u003e= 0)\n    \n    // good\n    const c = (d.length \u003e 0)\n    ```\n\n**[⬆ back to top](#contents)**\n\n## Template Strings\n\nExtends: [Section 6](https://github.com/airbnb/javascript#es6-template-literals)\n\n  \u003ca name=\"template-strings--call-function\"\u003e\u003c/a\u003e\n  - [9.1](#template-strings--call-function) Don't call function inside template string.\n    \u003e TODO: find or make ESLint rule for this\n\n    ```javascript\n    // bad\n    const targetURL = `${getHost()}/search/?query=${query}`\n    \n    \n    // good\n    const targetHost = getHost()\n    const targetURL = `${targetHost}/search/?query=${query}`\n    ```\n\n**[⬆ back to top](#contents)**\n\n## Objects\n\nExtends: [Section 3](https://github.com/airbnb/javascript#objects)\n\n  \u003ca name=\"objects--expression-assignment\"\u003e\u003c/a\u003e\n  - [10.1](#objects--expression-assignment) Do not mix expression in one-line objects as assignment.\n    \u003e TODO: find or make ESLint rule for this\n  \n    ```js\n    // bad\n    this.setState({ hasErrors: true, route })\n    \n    \n    // bad\n    const state = { hasErrors: true, route }\n    \n    \n    // good\n    this.setState({ hasErrors, route })\n    \n    \n    // good\n    this.setState({ hasErrors: true })\n    \n    \n    // good\n    const state = { hasErrors, route }\n    ```\n\n**[⬆ back to top](#contents)**\n\n## Classes \u0026 Constructors\n\nExtends: [Section 9](https://github.com/airbnb/javascript#classes--constructors)\n\n  \u003ca name=\"classes--static\"\u003e\u003c/a\u003e\n  - [11.1](#classes--static) Static members should be declared in class body\n    \u003e TODO: find or make ESLint rule for this\n  \n    ```javascript\n    // bad\n    \n    Profile.propTypes = {\n      classes: PropTypes.object.isRequired,\n      handleClick: PropTypes.func,\n    }\n    \n    \n    // good\n    \n    class Profile extends Component {\n    \n      static propTypes = {\n        classes: PropTypes.object.isRequired,\n        handleClick: PropTypes.func,\n      }\n    \n      // ...\n    }\n    ```\n\n**[⬆ back to top](#contents)**\n\n\n## Unsorted Yet\n  \n  \u003ca name=\"unsorted--brackets\"\u003e\u003c/a\u003e\n  - [12.1](#unsorted--brackets) Use brackets for expressions.\n    \u003e TODO: find or make ESLint rule for this\n\n    ```javascript\n    // bad\n    const useSrcKey = _srcKey !== undefined || this._srcKey !== undefined\n    const componentAsync = typeof src === 'function' ? src() : import(src)\n    const isProduction = process.env['NODE_ENV'] === 'production'\n    \n    // good\n    const useSrcKey = (_srcKey !== undefined) || (this._srcKey !== undefined)\n    const componentAsync = (typeof src === 'function') ? src() : import(src)\n    const isProduction = (process.env['NODE_ENV'] === 'production')\n    ```\n\n  \u003ca name=\"unsorted--dot-syntax\"\u003e\u003c/a\u003e\n  - [12.2](#unsorted--dot-syntax) Use dot syntax only for internal objects.\n    \u003e TODO: find or make ESLint rule for this\n    \n    Seperate importable/exportable JSON data objects and internal runtime objects.\n\n    Also it means - do not mix accessing to values by dot and by string.\n\n    \u003e [Google Closure Advanced Compilation](https://developers.google.com/closure/compiler/docs/api-tutorial3):\n    \u003e Whenever possible, use dot-syntax property names rather than quoted strings. Use quoted string property names only when you don't want Closure Compiler to rename a property at all. For example, to export a property you must use a quoted string. However, for properties used only within your compiled code, use dot syntax.\n\n    ```javascript\n    // bad\n    fetch('/api/users')\n      .then(response =\u003e response.json())\n      .then(json =\u003e {\n        if (!json.errors) {\n          json.data.users.forEach(user =\u003e {\n            const { id, name } = user\n            if (users[id].name !== name) {\n              setUserName(id, name)\n            }\n          })\n        }\n      })\n    \n    // bad\n    const a = { b: 1 }\n    console.log(a['b'])\n    \n    // bad\n    const a = { 'b': 1 }\n    console.log(a.b)\n    \n    // good\n    fetch('/api/users')\n      .then(response =\u003e response.json())\n      .then(json =\u003e {\n        if (!json['errors']) {\n          json['data']['users'].forEach(user =\u003e {\n            const id = user['id']\n            const name = user['name']\n            if (users[id].name !== name) {\n              setUserName(id, name)\n            }\n          })\n        }\n      })\n      \n    // good\n    const a = { b: 1 }\n    console.log(a.b)\n    \n    // good\n    const a = { 'b': 1 }\n    console.log(a['b'])\n    ```\n\n    It also means you can't rename stringifed keys because they are not in your code base only - in external API, data files, etc.\n  \n  \u003ca name=\"unsorted--jsx-js\"\u003e\u003c/a\u003e\n  - [12.3](#unsorted--jsx-js) Don't mix JS and JSX in one line.\n    \u003e TODO: find or make ESLint rule for this\n\n    ```javascript\n    // bad\n    return \u003cReferenceLink referenceKey={key} id={ref.id} title={ref.title}/\u003e\n    \n    \n    // bad\n    const body = items.map(it =\u003e \u003cli\u003e{it.title}\u003c/li\u003e)\n    \n    \n    // good\n    return (\n      \u003cReferenceLink referenceKey={key} id={ref.id} title={ref.title}/\u003e\n    );\n    \n    \n    // good\n    const body = items.map(it =\u003e (\n      \u003cli\u003e{it.title}\u003c/li\u003e\n    ))\n    \n    \n    // good\n    return (\n      \u003cReferences\u003e\n        {items.map((it, index) =\u003e (\n          \u003cReferenceLink referenceKey={index} id={it['id']} title={it['title']}/\u003e\n        ))}\n      \u003c/References\u003e\n    )\n    ```\n    \n  \u003ca name=\"unsorted--jsx-text\"\u003e\u003c/a\u003e\n  - [12.4](#unsorted--jsx-text) Don't mix JSX and Text node in one line.\n    \u003e TODO: find or make ESLint rule for this\n\n    ```javascript\n    // bad\n    return (\n      \u003cText style={style.openInSafariLink}\u003eOpen in Safari\u003c/Text\u003e\n    )\n    \n    \n    // good\n    return (\n      \u003cText style={style.openInSafariLink}\u003e\n        Open in Safari\n      \u003c/Text\u003e\n    )\n    \n    \n    // good - if you need a Text node for styling\n    return (\n      \u003cText\u003e\u0026nbsp;\u003c/Text\u003e\n    )\n    ```\n\n**[⬆ back to top](#contents)**\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faxept%2Fjavascript","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faxept%2Fjavascript","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faxept%2Fjavascript/lists"}