Setting Your JavaScript Free

by Loic Duros and Yuchen Pei

This explains how to release your JavaScript as free software so that it respects your users' freedom, and how to clearly indicate this fact so that LibreJS will validate it as released properly.

For an explanation of why it is crucial to make your JavaScript free, see The JavaScript Trap.

Step 1: Identifying all JavaScript on your page

Before you can add proper license information to your JavaScript, you must identify all the JavaScript present on your page.

GNU LibreJS can list both the blocked and accepted JavaScript code on a page and make this step much easier. To use it, enable LibreJS in IceCat, Abrowser, Iceweasel, or Firefox, and visit your page. Clicking on the LibreJS widget icon (top right of the screen) will show you which JavaScript code is blocked by LibreJS and which code is accepted.

External JavaScript files

External JavaScript files are easy to identify because they use a <script> element with a src attribute:

<script src="myfile.js"></script>

JavaScript embedded in a <script> tag

Many times, JavaScript code is directly embedded in a <script> tag, e.g.:

<script>
    var myString = "Hello World!";
    alert(myString);
</script>

JavaScript in event handlers

JavaScript can also be added to event handlers: inside an HTML attribute that is triggered at a specific moment or in a specific state. For instance, the following code will execute JavaScript when clicking on the link:

 <a href="#" onclick="alert('Hello World!')">Say Hello</a>

and the following will be executed right after the page has loaded:

 <body onload="alert('Hello World!')">

LibreJS also lists these elements for you in the display panel.

JavaScript embedded dynamically

Some advanced JavaScript constructs load a file of JavaScript code whose name is computed at run time. If LibreJS encounters these constructs in properly licensed free JavaScript code, it checks the files that they try to load, and tells you their names and whether they are free.

Other advanced JavaScript constructs execute JavaScript code computed by the program.

Since it is impossible for a machine to understand what that program does, LibreJS cannot tell what that code is or whether it is free.

You should only worry about these kinds of scripts after you have set proper licensing to all the other forms of JavaScript on your page and it is still not behaving as expected. This usually means LibreJS is blocking additional scripts that are loaded dynamically, and you need to add free license notices to them as well.

Step 2: Making decisions about your JavaScript

After you have a good idea of what JavaScript is present on your page, you should be able to divide all these scripts into three categories:

Scripts that are not yours, but are free

This is often the case with libraries, such as jQuery, Ember, Angular, and any other libraries or frameworks you're using. LibreJS detects many free libraries by default. For a current list of the JavaScript libraries that LibreJS whitelists by default, see script-libraries.json. There are too many JavaScript libraries and versions of those libraries for LibreJS to keep track of, so you will likely need to add license information for the libraries you use. By looking at the source code or checking the upstream site, you should be able to tell what license is being used. Please ensure these licenses are free and GPL-compatible.

Scripts that are not yours and are not free

On many websites you can find third-party code that is not free. This is often the case with Analytics trackers, Social Media widgets, JavaScript code that displays advertising, or third-party comment widgets.

Please take the time to request the provider of this script to release it under a free license. But unless they do so, freeing your site requires removing or replacing this JavaScript code.

Often you can find existing free replacements for the functionality of the nonfree script. We would like to help you; write to help-librejs@gnu.org.

In some cases (analytics and social media sites), what the code does is give information about your users to companies. That would be a bad thing for your site to do even if it were done with free software. The right way to do analytics is with free software such as Matomo. That way you don't give information about your site's visitors to anyone.

Scripts that are yours

If some of the JavaScript is yours, then you can decide to release it under a free license. We recommend you use the GNU General Public License version 3 or later. You can find a list of licenses detected as free by LibreJS in the project's documentation.

Step 3: Adding license information

Once you have removed nonfree JavaScript from your page and have a good idea of what JavaScript is free, you can go ahead and add proper license information to your page and your external scripts.

JavaScript Web Labels

The easiest way to add license information for sites using many different scripts is by making a JavaScript Web Labels table. For an example of a JS web labels table, see weblabels.fsf.org. In order to use this method, create an HTML page in your site. For instance, you could write the file in about/javascript.html on your website. This new page should have a simple HTML table inside of it. Other HTML elements such as your site's template can be present too. The information table should look something like this:

<table id="jslicense-labels1">
    <tr>
        <td><a href="/js/jquery-2.1.1.min.js">jquery-2.1.1.min.js</a></td>
        <td><a href="http://www.jclark.com/xml/copying.txt">Expat</a></td>
        <td><a href="/js/jquery-2.1.1.js">jquery-2.1.1.js</a></td>
    </tr>
    <tr>
        <td><a href="/js/my-javascript-code.min.js">my-javascript-code.min.js</a></td>
        <td><a href="http://www.gnu.org/licenses/gpl-3.0.html">GNU-GPL-3.0-or-later</a></td>
        <td><a href="/js/my-javascript-code.js">my-javascript-code.js</a></td>
    </tr>
</table>

Its id should be set to jslicense-labels1. For each external script, add a table row (<tr>). In each row, the first cell (<td>) must contain a link to the JavaScript file. The second column contains the name of the license with the canonical URL to the license. Finally, the third column contains a link to the original source code.

LibreJS identifies the licenses for these scripts using the canonical URL in the second column. A list of the licenses currently detected along with their canonical URL is available in the GNU LibreJS documentation.

Finally, you must add a link to the new page from all the pages loading these files. You can tell LibreJS about the link by setting either rel="jslicense" or data-jslicense="1" on the <a> tag.

<a href="/about/javascript" rel="jslicense">JavaScript license information</a>
or:
<a href="/about/javascript" data-jslicense="1">JavaScript license information</a>
rel="jslicense" doesn't pass HTML5 validation, so if that's an issue you can safely use data-jslicense="1".

When you use the JavaScript Web Labels method, you should still include a license notice at the top of each of your source files. This ensures that if someone copies the file and uses it for something else, the license remains intact.

More information on the JavaScript Web Labels is available here and in the JavaScript Web Labels rationale document.

Other Methods

JavaScript embedded on your page and in event handlers: Adding license information for the entire page

The embedded JavaScript code can be read directly from the HTML source of the page. This excludes external scripts that are loaded with the src attribute. You must release all of this embedded code under a free license, using the stylized comment. The license comment should be the first piece of JavaScript code available on the page. To ensure this is the case, we recommend you place the comment in its own <script> tag, before all the other scripts, e.g.:

<!doctype html>
<html>
    <head>
        <title>My Page</title>

        <meta charset="UTF-8" />

        <script>
        /*    
        @licstart  The following is the entire license notice for the 
        JavaScript code in this page.

        Copyright (C) 2014  Loic J. Duros

        The JavaScript code in this page is free software: you can
        redistribute it and/or modify it under the terms of the GNU
        General Public License (GNU GPL) as published by the Free Software
        Foundation, either version 3 of the License, or (at your option)
        any later version.  The code is distributed WITHOUT ANY WARRANTY;
        without even the implied warranty of MERCHANTABILITY or FITNESS
        FOR A PARTICULAR PURPOSE.  See the GNU GPL for more details.

        As additional permission under GNU GPL version 3 section 7, you
        may distribute non-source (e.g., minimized or compacted) forms of
        that code without the copy of the GNU GPL normally required by
        section 4, provided you include this license notice and a URL
        through which recipients can access the Corresponding Source.   


        @licend  The above is the entire license notice
        for the JavaScript code in this page.
        */
        </script>

        <script>
            // some JavaScript comes here and further down
            // the document.
        </script>

    </head>
    ...

You need not worry about whitespaces and new lines. The @licstart and @licend lines are needed so that it is explicit that all the JavaScript on the page is free.

As mentioned in the previous section, you can find a list of licenses detected as free by LibreJS in the project's documentation.

More information on the stylized comment is available in Appendix A of the JavaScript Trap.

After adding a license notice similar to the one above, all the JavaScript directly present on the page will be detected as free by LibreJS, and it will go on to analyze the external scripts individually.

LibreJS 5.0 introduced a new method to tag your JavaScript as free using special comments and magnet links pointing to the license files.

Instead of adding a license notice between @licstart and @licend, you simply add the following comments at the top and bottom of the script:

<script>
// @license [magnet-link] [human readable name of the license]
... [script is here] ...
// @license-end
</script>

You can also use the /* */ comment format:

<script>
/* @license [magnet-link] [human readable name of the license] */
... [script is here] ...
/* @license-end */
</script>

For a script released under the GPLv3 or later, this would become:

<script>
// @license magnet:?xt=urn:btih:1f739d935676111cfff4b4693e3816e664797050&dn=gpl-3.0.txt GPL-v3-or-Later
var myString = "Hello World!";
alert(myString);
// @license-end
</script>

After adding the correct license, this specific script will appear as free to LibreJS. Please note that the human readable string does not require a specific formatting, only the magnet link is checked. Please note that no code or comment should be added to the script after the // @license-end comment. However, whitespace is allowed.

List of magnet links for valid licenses

See the list in the project's documentation.

Please note: When people speak of the "MIT license" they mean either the X11 license or the expat license. Please see which license the code uses, and label it accordingly.

External JavaScript files

The external JavaScript files that are added using the <script src=".."> attribute and the scripts that are embedded dynamically are analyzed individually by LibreJS. Each of them may have a different free license.

Stylized comment

For external scripts, you can use the same sort of stylized comments as the HTML page. If your JavaScript file is minified or obfuscated in any way, please remember to add a @source line with the location of a source file:


/**
 *
 * @source: http://www.lduros.net/some-javascript-source.js
 *
 * @licstart  The following is the entire license notice for the 
 *  JavaScript code in this page.
 *
 * Copyright (C) 2014  Loic J. Duros
 *
 *
 * The JavaScript code in this page is free software: you can
 * redistribute it and/or modify it under the terms of the GNU
 * General Public License (GNU GPL) as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version.  The code is distributed WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU GPL for more details.
 *
 * As additional permission under GNU GPL version 3 section 7, you
 * may distribute non-source (e.g., minimized or compacted) forms of
 * that code without the copy of the GNU GPL normally required by
 * section 4, provided you include this license notice and a URL
 * through which recipients can access the Corresponding Source.
 *
 * @licend  The above is the entire license notice
 * for the JavaScript code in this page.
 *
 */

You can also use the // @license [magnet-link] and // @license-end notation for external scripts in the same way as scripts directly embedded on a page. Please read Method 2: Specific license information for each script for information on how to do this.

Step 4: Testing

To test the LibreJS-compliance of your webpage, apart from observing the LibreJS icon and its popup frame in the browser, you may do so from the command line, see the section titled "HEADLESS COMPLIANCE CHECK" in the README file.

If you need any assistance releasing your JavaScript under free licenses, please contact help-librejs@gnu.org.