Based on http://html5-demos.appspot.com/static/a.download.html: (archived)

var fileContent = "My epic novel that I don't want to lose.";
var bb = new Blob([fileContent ], { type: 'text/plain' });
var a = document.createElement('a');
a.download = 'download.txt';
a.href = window.URL.createObjectURL(bb);
a.click();

Modified the original fiddle: http://jsfiddle.net/9av2mfjx/

Answer from Stanislav on Stack Overflow
🌐
4umi
4umi.com › web › javascript › filewrite.php
Writing to the local file system - 4umi useful Javascript
It is not possible to change the doctype or to save anything else in the document head section. Tags will be made uppercase and whitespace normalized. The filename may end in .htm depending on the preference set in your Folder Options.... It will be clear that control is very limited and more advanced uses, with filenames ending in .css for instance, are ruled out. Writing to the local filesystem with absolute power requires an ActiveXObject and the 'Scripting.FileSystemObject'.
Discussions

html - Is it possible to write data to file using only JavaScript? - Stack Overflow
I want to write data to an existing file using JavaScript. I don't want to print it on console. I want to actually write data to abc.txt. I read many answered questions but everywhere they are prin... More on stackoverflow.com
🌐 stackoverflow.com
Save a string to a local file - Post.Byes
Is there a way I can save a string, locally, on the user's machine, offering them the chance to save it to a filename? Thanks, Ike More on post.bytes.com
🌐 post.bytes.com
javascript - How to generate and prompt to save a file from content in the client browser? - Stack Overflow
I have a situation where I need to give my users the option to save some data stored locally in their client memory to disk. The current workaround I have is having a handler like this (define-han... More on stackoverflow.com
🌐 stackoverflow.com
Save HTML locally with Javascript - Stack Overflow
I know that client-side Javascript cannot write data to the local filesystem, for obvious security reasons. The only way to save data locally with Javascript seems to be with cookies, localStorage,... More on stackoverflow.com
🌐 stackoverflow.com
🌐
SitePoint
sitepoint.com › javascript
How do I write to a local file using javascript - JavaScript - SitePoint Forums | Web Development & Design Community
March 24, 2020 - Greetings to the community. Hope you’re all doing OK. I’m using javascript for programming on my own computer (not for a webpage on the net) so the usual security concerns are not an issue. How do I write to a file on my own computer? I can write and retrieve a string using local storage e.g. window.localStorage.setItem(‘games’, games) and window.localStorage.getItem(‘games’), but I’d like to be able to write strings to a file on my computer.
🌐
GitHub
gist.github.com › liabru › 11263260
Save a text file locally with a filename, by triggering a download in JavaScript · GitHub
A solution is to probably stick with manually downloading through the element appended somewhere. function appendDownloadableText(filename, string) { const data = new Blob([string]); const url = URL.createObjectURL(data); const a = ...
🌐
Jotform
jotform.com › blog › advice › html5: filesystem api - create files and store them locally using javascript and webkit
HTML5: FileSystem API - Create Files and Store Them Locally Using JavaScript and Webkit | Jotform Blog
April 3, 2023 - The FileSystem-API allows the creation of files and folders as well as their local storage using JavaScript. Files can be simple text files, but even more complex files such as images are possible. Modern Webkit browsers with HTML5 support are already able to handle the FileSystem-API. We show you how you can benefit from the new possibilities. ... To be able to save files and folders from inside the web browser to the local hard drive you’ll need access to the filesystem.
Top answer
1 of 11
289

You can create files in browser using Blob and URL.createObjectURL. All recent browsers support this.

You can not directly save the file you create, since that would cause massive security problems, but you can provide it as a download link for the user. You can suggest a file name via the download attribute of the link, in browsers that support the download attribute. As with any other download, the user downloading the file will have the final say on the file name though.

var textFile = null,
  makeTextFile = function (text) {
    var data = new Blob([text], {type: 'text/plain'});

    // If we are replacing a previously generated file we need to
    // manually revoke the object URL to avoid memory leaks.
    if (textFile !== null) {
      window.URL.revokeObjectURL(textFile);
    }

    textFile = window.URL.createObjectURL(data);

    // returns a URL you can use as a href
    return textFile;
  };

Here's an example that uses this technique to save arbitrary text from a textarea.

If you want to immediately initiate the download instead of requiring the user to click on a link, you can use mouse events to simulate a mouse click on the link as Lifecube's answer did. I've created an updated example that uses this technique.

  var create = document.getElementById('create'),
    textbox = document.getElementById('textbox');

  create.addEventListener('click', function () {
    var link = document.createElement('a');
    link.setAttribute('download', 'info.txt');
    link.href = makeTextFile(textbox.value);
    document.body.appendChild(link);

    // wait for the link to be added to the document
    window.requestAnimationFrame(function () {
      var event = new MouseEvent('click');
      link.dispatchEvent(event);
      document.body.removeChild(link);
    });

  }, false);
2 of 11
113

Some suggestions for this -

  1. If you are trying to write a file on client machine, You can't do this in any cross-browser way. IE does have methods to enable "trusted" applications to use ActiveX objects to read/write file.
  2. If you are trying to save it on your server then simply pass on the text data to your server and execute the file writing code using some server side language.
  3. To store some information on the client side that is considerably small, you can go for cookies.
  4. Using the HTML5 API for Local Storage.
🌐
Robkendal
robkendal.co.uk › blog › 2020-04-17-saving-text-to-client-side-file-using-vanilla-js
Saving text to a client-side file using vanilla JS - Rob Kendal
April 17, 2020 - Want to save files to the client using JavaScript? Let's look at how to save a file client-side using s simple handful of vanilla JavaScript
Find elsewhere
🌐
Post.Byes
post.bytes.com › home › forum › topic › javascript
Save a string to a local file - Post.Byes
Re: Save a string to a local file On Sun, 18 Jan 2004 16:05:14 GMT, Ike <rxv@hotmail.co m> wrote: [color=blue] > Is there a way I can save a string, locally, on the user's machine, > offering them the chance to save it to a filename?[/color] See the FAQ, Section 4.3 - How can I access the client-side filesystem?
🌐
TutorialsPoint
tutorialspoint.com › how-to-create-and-save-text-file-in-javascript
How to Create and Save text file in JavaScript?
October 31, 2023 - <html> <body> <h2>Create a text file and save it to local computer using JavaScript</h2> <p>Enter the file content:</p> <textarea placeholder="Enter your text here..."></textarea> <br/><br/> <button onclick="downloadFile()">Save File</button> <script> const downloadFile = () => { const link = document.createElement("a"); const content = document.querySelector("textarea").value; if (!content.trim()) { alert("Please enter some content!"); return; } const file = new Blob([content], { type: 'text/plain' }); link.href = URL.createObjectURL(file); link.download = "sample.txt"; link.click(); URL.revokeObjectURL(link.href); }; </script> </body> </html>
🌐
Envato Tuts+
code.tutsplus.com › home › coding fundamentals
How to Save a File With JavaScript | Envato Tuts+ - Code
June 19, 2022 - We create an object that contains different options for our file picker that shows up when we call the showFilePicker() method. We can suggest a name to save the file here and also pass an array of allowed file types to save.
🌐
Newfivefour
newfivefour.com › javascript-save-text-string-as-local-file.html
Loading...
So CSS grid lets align your divs in grids. It's more visual and slightly less confusing than flexbox but needs more css -- harder to quickly hack · Our grid will have a top spanning header, an image under the header to the left and a text area to the right of the image · But we want to centre ...
Top answer
1 of 13
31

You can just use the Blob function:

function save() {
  var htmlContent = ["your-content-here"];
  var bl = new Blob(htmlContent, {type: "text/html"});
  var a = document.createElement("a");
  a.href = URL.createObjectURL(bl);
  a.download = "your-download-name-here.html";
  a.hidden = true;
  document.body.appendChild(a);
  a.innerHTML = "something random - nobody will see this, it doesn't matter what you put here";
  a.click();
}

and your file will save.

2 of 13
9

Chromium's File System Access API (introduced in 2019)

There's a relatively new, non-standard File System Access API (not to be confused with the earlier File and Directory Entries API or the File System API). It looks like it was introduced in 2019/2020 in Chromium/Chrome, and doesn't have support in Firefox or Safari.

When using this API, a locally opened page can open/save other local files and use the files' data in the page. It does require initial permission to save, but while the user is on the page, subsequent saves of specific files do so 'silently'. A user can also grant permission to a specific directory, in which subsequent reads and writes to that directory don't require approval. Approval is needed again after the user closes all the tabs to the web page and reopens the page.

You can read more about this newish API at https://web.dev/file-system-access/. It's meant to be used to make more powerful web applications.

A few things to note about it:

  • By default, it requires a secure context to run. Running it on https, localhost, or through file:// should work.

  • You can get a file handle from dragging and dropping a file by using DataTransferItem.getAsFileSystemHandle

  • Initially reading or saving a file requires user approval and can only be initiated via a user interaction. After that, subsequent reads and saves don't need approval, until the site is opened again.

  • Handles to files can be saved in the page (so if you were editing local file '/path/to/file.txt', and reload the page, it would be able to have a reference to the file). They can't seemingly be stringified, so are stored through something like IndexedDB (see this answer for more info). Using stored handles to read/write requires user interaction and user approval.

Here are some simple examples. They don't seem to run in a cross-domain iframe, so you probably need to save them as an html file and open them up in Chrome/Chromium.

Opening and Saving, with Drag and Drop (no external libraries):

<body>
<div><button id="open">Open</button><button id="save">Save</button></div>
<textarea id="editor" rows=10 cols=40></textarea>
<script>
let openButton = document.getElementById('open');
let saveButton = document.getElementById('save');
let editor = document.getElementById('editor');
let fileHandle;
async function openFile() {
  try {
    [fileHandle] = await window.showOpenFilePicker();
    await restoreFromFile(fileHandle);
  } catch (e) {
    // might be user canceled
  }
}
async function restoreFromFile() {
  let file = await fileHandle.getFile();
  let text = await file.text();
  editor.value = text;
}
async function saveFile() {
  var saveValue = editor.value;
  if (!fileHandle) {
    try {
      fileHandle = await window.showSaveFilePicker();
    } catch (e) {
      // might be user canceled
    }
  }
  if (!fileHandle || !await verifyPermissions(fileHandle)) {
    return;
  }
  let writableStream = await fileHandle.createWritable();
  await writableStream.write(saveValue);
  await writableStream.close();
}

async function verifyPermissions(handle) {
  if (await handle.queryPermission({ mode: 'readwrite' }) === 'granted') {
    return true;
  }
  if (await handle.requestPermission({ mode: 'readwrite' }) === 'granted') {
    return true;
  }
  return false;
}
document.body.addEventListener('dragover', function (e) {
  e.preventDefault();
});
document.body.addEventListener('drop', async function (e) {
  e.preventDefault();
  for (const item of e.dataTransfer.items) {
    if (item.kind === 'file') {
      let entry = await item.getAsFileSystemHandle();
      if (entry.kind === 'file') {
        fileHandle = entry;
        restoreFromFile();
      } else if (entry.kind === 'directory') {
        // handle directory
      }
    }
  }
});
openButton.addEventListener('click', openFile);
saveButton.addEventListener('click', saveFile);
</script>
</body>

Storing and Retrieving a File Handle using idb-keyval:

Storing file handles can be tricky, since they can't be unstringified, though apparently they can be used with IndexedDB and mostly with history.state. For this example we'll use idb-keyval to access IndexedDB to store a file handle. To see it work, open or save a file, and then reload the page and press the 'Restore' button. This example uses some code from https://stackoverflow.com/a/65938910/.

<body>
<script src="https://unpkg.com/idb-keyval@6.1.0/dist/umd.js"></script>
<div><button id="restore" style="display:none">Restore</button><button id="open">Open</button><button id="save">Save</button></div>
<textarea id="editor" rows=10 cols=40></textarea>
<script>
let restoreButton = document.getElementById('restore');
let openButton = document.getElementById('open');
let saveButton = document.getElementById('save');
let editor = document.getElementById('editor');
let fileHandle;
async function openFile() {
  try {
    [fileHandle] = await window.showOpenFilePicker();
    await restoreFromFile(fileHandle);
  } catch (e) {
    // might be user canceled
  }
}
async function restoreFromFile() {
  let file = await fileHandle.getFile();
  let text = await file.text();
  await idbKeyval.set('file', fileHandle);
  editor.value = text;  
  restoreButton.style.display = 'none';
}
async function saveFile() {
  var saveValue = editor.value;
  if (!fileHandle) {
    try {
      fileHandle = await window.showSaveFilePicker();
      await idbKeyval.set('file', fileHandle);
    } catch (e) {
      // might be user canceled
    }
  }
  if (!fileHandle || !await verifyPermissions(fileHandle)) {
    return;
  }
  let writableStream = await fileHandle.createWritable();
  await writableStream.write(saveValue);
  await writableStream.close();
  restoreButton.style.display = 'none';
}

async function verifyPermissions(handle) {
  if (await handle.queryPermission({ mode: 'readwrite' }) === 'granted') {
    return true;
  }
  if (await handle.requestPermission({ mode: 'readwrite' }) === 'granted') {
    return true;
  }
  return false;
}
async function init() {
  var previousFileHandle = await idbKeyval.get('file');
  if (previousFileHandle) {
    restoreButton.style.display = 'inline-block';
    restoreButton.addEventListener('click', async function (e) {
      if (await verifyPermissions(previousFileHandle)) {
        fileHandle = previousFileHandle;
        await restoreFromFile();
      }
    });
  }
  document.body.addEventListener('dragover', function (e) {
    e.preventDefault();
  });
  document.body.addEventListener('drop', async function (e) {
    e.preventDefault();
    for (const item of e.dataTransfer.items) {
      console.log(item);
      if (item.kind === 'file') {
        let entry = await item.getAsFileSystemHandle();
        if (entry.kind === 'file') {
          fileHandle = entry;
          restoreFromFile();
        } else if (entry.kind === 'directory') {
          // handle directory
        }
      }
    }
  });
  openButton.addEventListener('click', openFile);
  saveButton.addEventListener('click', saveFile);
}
init();
</script>
</body>

Additional Notes

Firefox and Safari support seems to be unlikely, at least in the near term. See https://github.com/mozilla/standards-positions/issues/154 and https://lists.webkit.org/pipermail/webkit-dev/2020-August/031362.html

🌐
YouTube
youtube.com › watch
HOW TO SAVE DATA AS A FILE (E.G. SAVE.TXT) USING JAVASCRIPT - Part 1: Save / Load - YouTube
HOW TO SAVE DATA AS A FILE (E.G. SAVE.TXT) USING JAVASCRIPTPart 1: Save / Loadfunction func_savedata(data){ var string_data = JSON.stringify(data); var fil
Published   March 3, 2021
Top answer
1 of 3
15

Save to filesystem

Have a look at angular-file-saver

Or use the following code as a reference in saving a BLOB. Where the blob object is generated from a JSON Object. But extration to a TEXT file is also possible.

    // export page definition to json file
    $scope.exportToFile = function(){
        var filename = 'filename'       
        var blob = new Blob([angular.toJson(object, true)], {type: 'text/plain'});
        if (window.navigator && window.navigator.msSaveOrOpenBlob) {
            window.navigator.msSaveOrOpenBlob(blob, filename);
        } else{
            var e = document.createEvent('MouseEvents'),
            a = document.createElement('a');
            a.download = filename;
            a.href = window.URL.createObjectURL(blob);
            a.dataset.downloadurl = ['text/json', a.download, a.href].join(':');
            e.initEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
            a.dispatchEvent(e);
            // window.URL.revokeObjectURL(a.href); // clean the url.createObjectURL resource
        }
    }

Using LocalStorage

Saving to localStorage:

window.localStorage.setItem('key', value);

Getting from localStorage

window.localStorage.getItem('key');

Delete key from localStorage

window.localStorage.removeItem('key');

Or using the AngularJS module 'ngStorage'

Browser compatibility

Chrome - 4    
Firefox (Gecko) - 3.5    
Internet Explorer - 8    
Opera - 10.50    
Safari (WebKit) - 4

See live example (credits to @cOlz)

https://codepen.io/gMohrin/pen/YZqgQW

2 of 3
9
$http({

            method : 'GET',
            url : $scope.BASEURL + 'file-download?fileType='+$scope.selectedFile,
            responseType: 'arraybuffer',
            headers : {
                'Content-Type' : 'application/json'
            }

        }).success(function(data, status, headers, config) {
            // TODO when WS success
            var file = new Blob([ data ], {
                type : 'application/json'
            });
            //trick to download store a file having its URL
            var fileURL = URL.createObjectURL(file);
            var a         = document.createElement('a');
            a.href        = fileURL; 
            a.target      = '_blank';
            a.download    = $scope.selectedFile+'.json';
            document.body.appendChild(a);
            a.click();

        }).error(function(data, status, headers, config) {

        });

In success part need to open local system, by which the user can choose, where to save file. Here I have used <a>. And I am hitting restful service

🌐
Reddit
reddit.com › r/learnjavascript › how can i save a json value from html/javascript in a json file locally?
r/learnjavascript on Reddit: How can I save a json value from HTML/JavaScript in a json file locally?
December 29, 2021 -

I want to save some numbers from a small program in a local JSON file.

Example:

const increaseButton = document.getElementById("increase-button")
const numberField = document.getElementById("count-field")
let myNum = 0
let myArray = []
increaseButton.addEventListener("click", increaseNum)

function increaseNum() {
    myNum++
    numberField.innerText = myNum
    myArray.pop()
    myArray.push(myNum)
    let jsonString = JSON.stringify(Object.assign({}, myArray))
    console.log(jsonString)
}

The jsonString should be saved in a local file "myjson.json".

Goal: If I increase the number with the increaseButton, the new value should be saved in the "myjson.json" file:

{
    "numbers": {
        "0":1}
}

The only option I found was with node.js plugin "fs" and a lot of code. Couldn't it be easier?