Writing Code

How to edit a JavaScript file on Mac

You can do this with Note My. A .js file opens coloured, with a regex literal told apart from a division sign — here is what you get on a JavaScript file, from the first line you read to the last one you change.

You want to open a .js file on your Mac, read it without squinting, and change it without fighting the editor. Not a project, not a workspace to configure first — one file, opened quickly, coloured properly, with enough help while you type that you are not retyping identifiers from memory.

This guide covers what Note My gives you on a JavaScript file: what the colouring understands, what you are offered as you type, how to move around a long file, and what sits around the editor for the moments when you need more than an edit.

Note

It all happens on your Mac: nothing is uploaded, there is no account, and your files never leave the machine. Nothing you open or type is sent anywhere.

Open the file

  1. Open it the ordinary way

    Press ⌘O and pick the file, or drag it from the Finder onto the tab bar; each file arrives in its own tab. Right-clicking in the Finder and choosing Note My ▸ Open works too, as does Note My ▸ Open in Background when you do not want the window to jump forward.

  2. Check the language in the status bar

    The status bar shows the document's language; a .js file arrives as JavaScript with nothing to do. If it says something else, click the Identify pill to open the Language Inspector — a small card reading "Identified programming language: X" with an override pop-up, and Confirm or Cancel. A language you choose there sticks for the tab.

  3. Or paste into a new, empty tab

    Press ⌘N, paste a block of JavaScript, and our advanced language identifier sets the language once, quietly, with no sheet in your way — so a fragment with no filename still arrives coloured. That happens on a brand-new empty tab and only on paste: nothing you type changes the language under you, and a language you set yourself is never overruled. Propose-on-paste, an always-ask sheet, is off by default.

Why the language setting is worth a glance

The language in the status bar is the setting everything else on this page follows: the colouring, the keywords and built-ins you are offered, whether call tips and auto-import lines appear, and the conventions the Indentation sheet tidies your file to.

Most of the time there is nothing to do. A .js file opens as JavaScript, and our advanced language identifier covers code you paste into a new tab, so a snippet a colleague sent you is coloured before you have named it. The files worth a glance are the ones whose names give little away.

Setting a language changes what you see, never the file itself, so there is no risk in trying one. With a mixed file, pick the language you are editing.

What the colouring shows you

JavaScript is one of the 15 code languages our syntax engine colours — keywords, types, built-ins, literals, numbers, strings, comments and function names each get their own treatment, as do two universal conventions: UpperCamelCase is painted as a type, SCREAMING_SNAKE as a literal. Three details matter specifically in JavaScript.

  • Template literals are real multi-line strings. A backtick string keeps its colour across line breaks rather than stopping at the edge of the line.
  • ${…} interpolation is coloured as code. The expression inside the braces reads as code rather than as more string, so a mistake inside an interpolation is visible instead of hiding in a wall of one colour.
  • A regex literal is told apart from a division sign. Our syntax engine separates the two in JavaScript and TypeScript, which is the difference between a readable file and one where everything after a / turns the wrong colour.

Escape sequences stand out against the string colour, and an ordinary quoted string stops at the end of its line, so one unbalanced quote cannot recolour the rest of the file. None of the colour is written into your document: it is something you see on screen, and leaves nothing new to save.

Tip

Use the colour as a proof-reader. If a long run of the file has turned into string colour, scroll up to the nearest backtick and you will usually find the one you forgot to close. If an expression inside ${…} stays string-coloured, the braces are not balanced.

Code completion: six kinds of suggestion, one list

As you type an identifier, a floating panel offers six kinds of suggestion in one list, kept apart under their own section headings, with documentation beside it and a ghost preview of the highlighted row. It never takes the keyboard from you, so your typing carries on regardless.

The six kinds of completion suggestion and what each gives you in a JavaScript file
SuggestionWhat it gives you
Auto-importA symbol plus the import line to add, after a couple of characters.
PathFile paths written in the document, and the folders above them, once you are typing a path.
BuiltinsWell-known functions and types, with the signature and a short description beside the list.
Document symbolsThe declarations in the file you have open.
KeywordThe language's own keywords.
WordWords already in the document, the nearest ones first.

You do not have to type the start of a word: pri reaches printf. A few rows show at a time and the arrow keys reach the rest. If nothing matches, the panel steps aside and your typing carries straight on.

While the panel is up: arrows and Page keys move, ↩ and ⇥ accept (each separately switchable in Settings ▸ Code Suggestions), ⎋ dismisses, and ⌃M pins the highlighted path so it is offered in every other document. ⌃Space forces the panel open even when suggest-while-typing is off.

Accepting a suggestion that carries a template drops in placeholders written ${N:default} with the first argument selected; ⇥ jumps to the next and selects its default, so typing replaces it. Suggestions you accept float upward next time, kept per language.

Auto-import writes the import line for you

JavaScript is one of the four languages with auto-import, alongside TypeScript, Swift and Python. The suggestion is not just the symbol: accepting it puts the symbol where you were typing and adds the import line at the top of the file, leaving your caret where you left it. You never scroll up to the import block and back down again.

It draws on the well-known symbols of the language — the ones you reach for several times a day and still have to check the spelling of — so the import lines you write most often are the ones you stop writing. Type a couple of characters, take the row, and the top of the file has already caught up with the line you are on.

Call tips while you write a call

Press ⌃⇧Space, or carry on typing inside a call, and a small panel shows the signature with the argument you are currently on highlighted. JavaScript is one of the languages with call tips, and they cover both the well-known functions and the ones declared in the file you have open. What you read is the real signature rather than a guess at the arguments, so you can act on it without checking it first.

The highlighted argument stays the right one in awkward calls: a nested call or a default value can carry its own commas, and the highlight still sits on the argument you are actually typing. That is worth leaning on when a call runs long — glance at the panel instead of counting commas across three lines.

Smart editing in a JavaScript file

The toolbar's Smart Edit toggle shows its own state, and the five underlying switches — the master, Return, brackets, quotes and HTML tags — are all on by default.

  • Return carries your indentation. A new line starts level with the one you left, one step deeper after a trailing {, [, ( or :. If the matching closer is the next character, the pair opens onto three lines with your caret in the middle.
  • Six auto-pairs, and the backtick is one of them. (), [], {}, "", '' and ``. Typing an opener with text selected wraps the selection and re-selects the inner text.
  • Apostrophes are protected. A quote is not paired when the previous character is a letter or a digit, so don't stays as you typed it.
  • Typing a closer over an auto-inserted one just moves the caret past it — no text changes, so there is nothing extra to undo afterwards.

JSX inside a .js file rides on the same behaviour. The braces around a prop or an expression pair as you type, a new line starts level with the one you left, and typing a closer over an auto-inserted one moves the caret past it, so a block of markup stays lined up while you write it.

Moving around a long file

Double-click a brace and everything between it and its partner folds out of sight; double-click again, or click where the folded text was, or click the arrow in the gutter, and it comes back. Pairs are {}, () and []. Folding never touches your document, so it never marks the file as changed and there is nothing to save afterwards. It is a gesture rather than a mode: fold a long function away to read what surrounds it, then bring it back in a click.

Double-click an identifier instead and every other occurrence lights up. Whole names only, so id does not light up inside valid — the quickest way to see where a variable is used before you rename it. The status bar's Occ pill puts a number on it, so you know how many places you are about to touch without leaving the line you are on.

Double-click an identifier and every other use of it lights up, with a live count in the status bar. The match is whole-identifier and Unicode-aware, so total never matches inside subtotal.

⌘L goes to a line number, pre-filled with the line you are on and selected. A number past the end of the file is refused rather than quietly taking you to the last line, so you always know whether you arrived where you meant to.

Starting a new JavaScript file

Choose File ▸ New from Template, or the Templates pull-down in the toolbar — both open the same 40 built-in starting points from our template library, so a new file arrives with its language set. The Languages group includes main.js, and the Config group carries package.json, tsconfig.json, .editorconfig, .gitignore and a GitHub Actions ci.yml.

When you save, the Save As sheet pre-fills an extension to match the document's language, always one Note My opens in that same language — so the file comes back coloured rather than in a mode you set again. Type any name you like; the tab keeps its language.

Very large JavaScript files

A bundle or a minified library is bigger than anything you would write by hand, and those are the files that make an editor stall. Our large-file engine keeps the window responsive on them, and the status bar tells you when you are in a file of that size. Your file is handled on your Mac whatever its size.

On a file that size the suggestion list waits to be asked: press ⌃Space and it is there when you want it. Smart editing carries on throughout — indentation, pairing and type-over all work at any size, so editing one line of a minified bundle feels the same as editing one line of anything else.

Troubleshooting

The file opened as Plain Text

Sometimes a file arrives as Plain Text rather than JavaScript — a fragment saved out of a chat window, say, or a file that was never given an extension. Click the Identify pill in the status bar, choose JavaScript in the Language Inspector and confirm; that choice sticks for the tab. For a file you return to often, renaming it with a .js extension is tidier: it opens coloured every time.

The suggestion list has not appeared

Three things to call it back. On a very large document the list waits to be asked, so press ⌃Space to bring it up. Each kind of suggestion has its own switch in Settings ▸ Code Suggestions, so one may simply be off. And auto-import waits until you have typed a couple of characters.

Return accepted a suggestion when I wanted a new line

Acceptance by ↩ and acceptance by ⇥ are two separate switches in Settings ▸ Code Suggestions. Turn off whichever one is in your way; the other keeps working.

Taking a different row from the list

The row waiting for you is the first row of the first section. The ghost preview, ↩ and ⇥ all act on the highlighted row, so glance at the preview and arrow down to the row you actually want before accepting. To bring your favourites forward, turn off a section you rarely use in Settings ▸ Code Suggestions; the sections you keep move up the list.

A quote did not pair

That is the apostrophe protection at work: a quote typed straight after a letter or a digit is left alone. It keeps it's intact in a comment or a string, so prose inside your code comes out exactly as you typed it.

Double-clicking a brace folded the block instead of selecting it

That is the fold gesture: a double-click on a bracket folds, and a second double-click brings the block back, so nothing is lost either way. Double-clicking anything that is not a bracket selects the identifier and highlights its other occurrences as normal.

What else a JavaScript file gets

The editor is one part of it. A handful of tools sit around the file you have open, and they are worth knowing before the day you need them.

  • Run it where it lives. The tab's right-click menu offers Open in Terminal and Save and Open in Terminal. The second writes your changes and puts you at a shell prompt in the file's own folder, so node app.js is simply the next thing you type — no hunting for the path, no dragging the file into a window.
  • Change the same thing in every open tab. Our find and replace runs through the tabs you have open in one pass, so renaming a variable or swapping an endpoint is a single move rather than the same edit typed out tab after tab.
  • Search a folder you have not opened. ⇧⌘F reads every text file under a folder and lists what it finds as it arrives, grouped by file, and a double-click opens the file at that line.
  • Put two versions side by side. Our comparison view shows you what moved between one copy of a file and another, which is the quickest way to settle what actually changed since yesterday.
  • Find the character you cannot see. Our hidden-character scanner turns up the non-breaking space or the stray invisible that the eye slides straight past, and that a build will complain about later.
  • Repeat a fiddly edit. Our macro recorder captures a run of edits once so you can play it back down a long file instead of doing it forty times by hand.
  • Open a file written elsewhere. Our encoding handling takes a file that came from another machine and shows it the way it was meant to read.
  • Tidy the whole file at once. The toolbar Indent button opens the Indentation sheet, where our indentation engine puts a whole document on consistent depths in the brace style you choose. Nothing changes until you press Apply.

Our auto-recovery safety net sits underneath all of it, so an interrupted session finds your work waiting for you when you come back. And every one of these runs on your own Mac: nothing is uploaded, and nothing about the file you are editing goes anywhere.

Frequently asked questions

Does it handle TypeScript as well as JavaScript?

Yes. TypeScript is one of the 15 coloured languages, and it is one of the four with auto-import. The template-literal and regex-versus-division handling described above is shared between JavaScript and TypeScript.

Does syntax colouring change my file?

Colour is something you see on screen, never something written into the text, so it leaves your file exactly as you wrote it: the document is not marked as changed, and the saved bytes are the ones you typed. Exporting to HTML, RTF or PDF does carry the colours across, because a coloured export is the point of that command.

Can I reformat a messy JavaScript file?

Yes, through the toolbar Indent button, which opens the Indentation sheet. Pick JavaScript, choose a brace style — K&R on the same line, or Allman on the next — set the indent width, and press Apply. Our indentation engine then puts the whole file on consistent depths. Nothing changes before then, and the sheet's preview shows you how each brace style looks while you decide.

Save the file with ⌘S before you press Apply, and you keep a way back: File ▸ Reload from Disk (⌘R) brings the saved version straight into the tab if you would rather keep the layout you had. Reloading never changes the file on disk, so you can look and decide again.

Can I shape what gets suggested to me?

Yes, in three ways. Each kind of suggestion has its own switch in Settings ▸ Code Suggestions, so you keep the sections you use and quieten the rest. The suggestions you accept float upward next time, kept separately per language, so the list learns the way you write JavaScript. And ⌃M pins the highlighted path so it is offered in every other document you open.

Suggestions that carry a template bring their placeholders with them, written ${N:default}, with ⇥ moving you from one argument to the next.

How do I search across a whole project folder?

⇧⌘F opens Find in Folder — a window that searches every text file under a folder and lists results as they arrive, grouped by file, double-click to open at the line. It only ever reads your files. When you want to change what you have found, open the file and hand it to our find and replace, which works across the tabs you have open.

Will it edit my package.json too?

Yes, and the Edit menu adds Format JSON, Minify JSON and Validate JSON. Format lays the file out with a two-space indent and sorts the keys, which makes two versions of a manifest easier to compare. Validate reports without changing a character, and gives the line and column of the problem.