{"id":18975046,"url":"https://github.com/bufferapp/javascript-style-guide","last_synced_at":"2026-04-08T18:30:18.551Z","repository":{"id":17721931,"uuid":"20548927","full_name":"bufferapp/javascript-style-guide","owner":"bufferapp","description":"Buffer's JavaScript style guide","archived":false,"fork":false,"pushed_at":"2015-01-19T18:41:50.000Z","size":324,"stargazers_count":23,"open_issues_count":0,"forks_count":5,"subscribers_count":41,"default_branch":"master","last_synced_at":"2025-01-01T09:09:34.110Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"DaveOsment/aws-ebs-snapshots-lambda","license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bufferapp.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":"2014-06-06T02:32:23.000Z","updated_at":"2024-08-30T21:36:02.000Z","dependencies_parsed_at":"2022-09-22T14:41:21.304Z","dependency_job_id":null,"html_url":"https://github.com/bufferapp/javascript-style-guide","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bufferapp%2Fjavascript-style-guide","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bufferapp%2Fjavascript-style-guide/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bufferapp%2Fjavascript-style-guide/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bufferapp%2Fjavascript-style-guide/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bufferapp","download_url":"https://codeload.github.com/bufferapp/javascript-style-guide/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239972557,"owners_count":19727400,"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":[],"created_at":"2024-11-08T15:17:08.340Z","updated_at":"2026-04-08T18:30:18.517Z","avatar_url":"https://github.com/bufferapp.png","language":null,"readme":"# Buffer JavaScript Style Guide\n\n*A work in progress inspired by [AirBnB's Style Guide](https://github.com/airbnb/javascript).*\n\n## Goal\n\nTo establish more consistency and readability across the Buffer team and our\nopen source projects.\n\n## Ideals\n\n\u003e **Have a bias toward clarity** - from [The Buffer Values](http://www.slideshare.net/Bufferapp/buffer-culture-04)\n\n  - We should always aim to write code that is clear and readable.\n  - Use whitespace. Add comments liberally where needed, but strive to write code that's clear and self documenting\n  - Always try to write code that clearly demonstrates and communicates it's intent.\n\n## Table of Contents\n\n  1. [Naming Conventions](#naming-conventions)\n  2. [Variables](#variables)\n  3. [Strings](#strings)\n  4. [Blocks](#blocks)\n  5. [Whitespace](#whitespace)\n  6. [jQuery](#jquery)\n  7. [Scope \u0026 this](#scope--this)\n\n*Future sections may include: Commas+Semicolons, Comments,\nConditional Expressions, Variables, Properties*\n\n## Naming Conventions\n\n  - Use camelCase variables and function names. use CAPS_UNDERSCORE for constants.\n\n    ```javascript\n    var updateText = 'Point Break is the best movie ever.';\n\n    function setUpdateText(arg) { //...\n\n    // Constants\n    var MAX_TWEET_LENGTH = 140;\n    ```\n\n  - Use PascalCase or CapFirst when creating a constructor or extending a\n    Backbone class. Avoid using a capital first letter unless it's one of these.\n\n    ```javascript\n    function Profile(service){\n      this.service = service;\n    }\n    \n    var myProfile = new Profile('facebook');\n\n    var ProfileView = Backbone.View.extend({\n      events: {}\n    });\n    ```\n\n  - Use a leading _ to denote private methods\n\n    ```javascript\n    MyClass.prototype._privateMethod = function(){ //...\n    ```\n\n  - Be descriptive in the variables purpose.\n\n    ```javascript\n    var isFacebook = profile.get('service') === 'facebook';\n    // over...\n    var facebook = profile.get('service') === 'facebook';\n    ```\n\n## Variables\n\n  - Remember to use `var` to declare your variables and avoid poluting the global namespace.\n  - Use one `var` declaration per line. Avoid re-use of a single `var` declaration. \n    This helps keep our commits simple when adding removing a variable since we won't have \n    to edit spacing or commas/semi-colons.\n    \n    ```javascript\n    var open = false;\n    var count = someCollection.length;\n    ```\n    \n  - Declare unassigned variables last. This helps keep organized and shows what will be assigned \n    throughout a function.\n\n    ```javascript\n    // good :)\n    var input = document.querySelectorAll('.js-my-input');\n    var text = input.value;\n    var isOverLimit;\n    \n    if (profile.get('service') === 'twitter') {\n      isOverLimit = text \u003e 140;\n    }\n    \n    if (isOverLimit) {\n      // ...\n    }\n    \n    // ...not great :(\n    if (profile.get('service') === 'twitter') {\n      var isOverLimit = text \u003e 140;\n    }\n    \n    // variable may be undefined here\n    if (isOverLimit) {\n      // ...\n    }\n    ```\n    \n  - Assign variables at the top of functions. This avoids issues with hoisting and variable declaration\n    \n    ```javascript\n    function myFunc($container) {\n      var someBoolean = false;\n      var isOpen;\n      \n      // ...other logic\n      \n      if (someBoolean === true) {\n        isOpen = $container.hasClass('.open');\n      }\n  \n      // ...some more logic\n    }\n    ```\n  \n\n## Strings\n\n  - Use single quotes `''` over double quotes for strings.\n\n    ```javascript\n    var update = 'Some text';\n    ```\n\n  - Strings longer than 80 characters should be written across multiple lines\n    using string concatenation. Use `+` for concatenation, avoid escaping EOLs\n    with `\\`.\n\n    ```javascript\n    var update = 'Grounds, half and half, affogato sit medium, decaffeinated ' +\n        'cortado, acerbic whipped grinder cultivar aftertaste. Sugar, wings ' +\n        'robusta barista, seasonal robust, mazagran qui blue mountain organic ' +\n        'breve arabica.';\n\n    // or use Array#join\n    var update = [\n        'Grounds, half and half, affogato sit medium, decaffeinated ',\n        'cortado, acerbic whipped grinder cultivar aftertaste. Sugar, wings ',\n        'robusta barista, seasonal robust, mazagran qui blue mountain organic ',\n        'breve arabica.'\n    ].join('');\n    ```\n\n## Blocks\n\n  - Use curlys `{}` for multi-line blocks, add spacing around statements to\n    encourage readability.\n\n    ```javascript\n    if ( update.get('text').length \u003c 140 ) {\n      update.save();\n    } else {\n      $('.js-warning').show();\n    }\n\n    // It's ok to drop the braces if it's a short one-liner, try to keep it\n    // under ~80 characters long so it's readable\n    if ( update.get('text') \u003e 140 ) this.showLengthWarning();\n\n    ```\n\n## Whitespace\n\n  - Use soft tabs set to **2** spaces.\n\n    ```javascript\n    function isAwesome() {\n    ∙∙return this.plan === 'awesome';\n    }\n    this.getDataForModel(123)\n    ∙∙.then(this.renderTemplate);\n\n    // instead of\n    function isBusiness() {\n    ∙∙∙∙return ['small', 'business', 'agency'].indexOf(this.plan) \u003e -1;\n    }\n    this.getDataForModel(456)\n    .then(this.renderTemplate);\n    ```\n\n  - Use whitespace with operators\n\n    ```javascript\n    var count = x + 2;\n    // instead of\n    var count=x+2;\n    ```\n\n  - Use indentation for longer method chaining\n\n    ```javascript\n    $update\n      .text(newText)\n      .removeClass('editing')\n      .addClass('saved');\n\n    // Instead of\n    $update.text(newText).removeClass('editing').addClass('saved');\n    ```\n\n## jQuery\n\n  - Use `.js-` prefixed class selectors. This prevents confusion between\n    classes needed for design and ones used to reference the DOM from js.\n\n    ```html\n    \u003cdiv class=\"update js-update-content\"\u003eSome update text\u003c/div\u003e\n    ```\n\n    ```javascript\n    var $content = $('.js-update-content');\n    $content.text('New text');\n    ```\n\n  - Prefix jQuery object variables with a `$`. This makes it easier to distingush jQuery variables vs other variables and DOM elements.\n\n    ```javascript\n    var $sidebar = $('.js-sidebar');\n    ```\n\n  - Cache jQuery lookups.\n\n    ```javascript\n    // Use this...\n    var $sidebar = $('.js-sidebar');\n    $sidebar.addClass('hidden');\n    $sidebar.data('id', '1234');\n\n    // Instead of\n    $('.js-sidebar').addClass('hidden');\n    $('.js-sidebar').data('id', '1234');\n    ```\n\n  - Use Promises with $.ajax. jQuery's docs use them as the new default. Use `.then` or `.always` over `.done` and `.fail`\n\n    ```javascript\n    $.ajax({ url: '/updates.json' })\n      .then(function(data){\n        renderUpdates(data.updates);\n      }, function(){\n        alert('Request failed');\n      });\n\n    // Promises also work nicely for wrapping a more complex $.ajax request\n    function saveUpdateText(updateId, text) {\n      return $.ajax({\n        type: 'post'.\n        url: '/updates/' + updateId + '.json',\n        data: {\n          body: text\n        }\n      });\n    }\n\n    // The response\n    function showSuccessNotification(data) {\n      new Notification(data.message);\n    }\n\n    // Usage is very clean and easy to read\n    saveUpdateText(123, 'My new update text')\n      .then(showSuccessNotification);\n\n    ```\n\n## Scope \u0026 this\n\n  - Use `.bind(this)` to pass scope to functions if possible.\n    Use `var _this = this;` if it makes your code simpler and more readable.\n\n    ```javascript\n    someMethod: function(data) {\n      this.saveMyUpdate(data)\n        .then(function(data){\n          this.collection.add(data);\n          this.showSavedNotification();\n        }.bind(this));\n    }\n\n    var myUpdates = updates.filter(function(update){\n      return update.type === this.getCurrentType();\n    }.bind(this));\n\n    // Using _this - Maybe this isn't the best example, but you get the idea :)\n    loadModelDataInForm: function(id){\n      var _this = this;\n      $.ajax({ url: '/model/' + id + '/' })\n        .then(function(data){\n          _this.renderTemplate(data);\n          $('.js-save-button').on('click', function(e){\n            $(this).text('Saving...');\n            _this\n              .getDataFromForm()\n              .save();\n          });\n        }, function(err){\n          alert(err);\n        });\n    }\n    ```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbufferapp%2Fjavascript-style-guide","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbufferapp%2Fjavascript-style-guide","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbufferapp%2Fjavascript-style-guide/lists"}