Deno, Grammarly, and Windows
This article documents a use case I have for Deno on Windows. It describes what Deno is, why I wanted to use it, some issues I ran into, and how I solved those issues.
What is Deno and why use it?
Deno is a secure runtime for JavaScript and TypeScript. While it is still experimental, it is set to eventually replace and improve on Node for many use cases. Version 1 is scheduled to release May 2020. Compared to Node, Deno is relatively secure, web-friendly, and provides native TypeScript support.
I'm currently a Principal Software Engineer at Capital One and I use Node daily. In case my credentials don't convince you of my claims on Deno's superiority, perhaps you will be convinced by this talk from Ryan Dahl, the creator of Node. By the way, he's also the creator of Deno. Here's another recommended talk on Deno. The second talk is a more recent talk by Bert Belder, another great engineer and former Node core contributor.
Node is a server-side JavaScript run time. JavaScript is the most common programming language on the planet. JavaScript is implemented as a web client in all major web browsers. TypeScript compiles to JavaScript, and modern web applications are increasingly written in TypeScript. All of this information highlights the value of Deno, in addition to the obvious value from security.
A result of the above facts is that Node is currently a go-to tool for scripting filesystem operations for many people including myself, and Deno is on track to replace Node, although it will be a matter of years before that happens. A further result is that I've been looking for simple use cases where trying out Deno would be an opportunity so that I can get ahead of the curve with this skill. I recently found an appropriate case.
What use case?
I'm writing an academic paper on the effects of Section 127 employer educational assistance. I would like to run this paper through spelling and grammar check, but I'm using LaTeX compiled to PDF. Microsoft Word and Grammarly are two well-known tools for spelling and grammar check, but neither of them runs directly on LaTeX or PDF. Both of them would support a plain text version of my paper, so my use case is a need to translate either PDF or LaTeX into plain text.
Installing Deno on Windows 10 with WSL2 and Git Bash
I'm using Windows 10. Installing Deno was immediately a problem. Installation instructions indicate that curl works, but downloading curl installed a Windows-incompatible package. I created this GitHub issue for that issue.
The installation instructions explicitly indicated the use of Chocolatey package manager for Windows. I attempted this approach, but I ran into issues installing Chocolately with Git bash. This doesn't surprise me. I've never had a good experience with Chocolately. I think it pails in comparison to other package managers including Homebrew, Yum, or even the questionable NPM.
One might ask why I insist on using git bash. Windows-native PowerShell does not provide this, so git bash has historically been a widely used approach to achieving bash support on Windows. Bash support is important because it is the standard console API for web applications today. The most common, performant, secure, and preferred servers use a Linux operating system, and macOS also natively supports bash. Bash is implemented in various ways for Windows users as well, while PowerShell is not widely used on macOS or Linux. So bash is also the most universal and portable kind of console.
Over the past year, however, Microsoft has produced Windows Subsystem for Linux, version 2, also called WSL or WSL2, but be careful when you hear WSL alone. The version here is important. The first version was a Linux emulator, but the second version uses a real Linux kernel. Here's a great explainer article regarding other WSL2 features. At this point I was faced with two options:
- Try to install Deno using PowerShell, but use Deno via Git bash after installation, or
- Install and use Deno via WSL2. Stop using Git bash.
If WSL2 behaves properly, option 2 seems to be a new best practice. However, many people will face switching costs and it doesn't hurt to briefly investigate option 1. On investigation, it seems the Deno instructions for installation via PowerShell also fail at the time of writing. I filed a separate GitHub issue here.
I proceeded to install WSL2 as described here on Microsoft's site. After enabling WSL, I notice that wsl help
works within Git bash. After enabling WSL2, I installed the Ubuntu image into my workspace using curl from Git bash with the command curl.exe -L -o ubuntu-1604.appx https://aka.ms/wsl-ubuntu-1604
. My workspace is a folder called workspace
which is at the top level of a storage drive. The result is a Ubuntu .appx
file at /d/workspace/ubuntu-1604.apptx
.
I then added this image into WSL2 via PowerShell by running Add-AppxPackage .\\app_name.appx
within my workspace folder. About this time I noticed that VS Code had intelligently detected my WSL install and recommended a VS Code extension for easier WSL use. I did so.
.appx
files are Windows application packages, so by running the command above which added the package, I now literally open the Ubuntu app by using \"Windows key + s\" to search for the app and click it. I could have also used the app store or perhaps found the app in the start menu. This kicks off a new terminal which is a real Ubuntu shell. Ubuntu installs and asks me for a username and password, then logs me in.
I now find myself in a strange and beautiful Ubuntu Linux view of my filesystem. It is the same Windows filesystem, not a virtual machine with a distinct file system. I navigate to my workspace within the Ubuntu shell by using cd /mnt/d/workspace
.
I now, for the second time, attempt to install Deno using curl
. To reiterate, there are now two key differences compared to the first time I tried curl-based installation:
- I am now in a real bash shell with a real Linux kernel in a Ubuntu operating system context, and the OS context is inside WSL2.
- I am not using git bash.
I copy the curl command from Deno's website and attempt to paste it into the Ubuntu shell. It doesn't work. I found this Stack Exchange answer which shows how to easily enable the shared clipboard. I try to curl again. The curl works, but unzip
command is not found. This is great news! Real Ubuntu doesn't come with a built-in unzip
command. I use sudo apt-get install unzip
and it works exactly as expected. I run curl again and Deno is successfully installed! I also notice the Ubuntu application terminal has working tab completion, just like real bash. Evidence continues to mount that I am using real bash and Linux, not another Microsoft mutation of bash or Linux.
One negative is that I notice WSL currently forces subsystem package installations to be stored on my main drive. So far this would include deno
and unzip
. This puts my main drive near capacity quickly. I created this GitHub issue on WSL to enable storing subsystem-installed packages on a remote storage drive.
Another compliment to WSL ergonomics is that the filesystem seems perfectly in sync. With a Ubuntu session open, I edited a folder name in Windows file explorer. When I run ls
in the Ubuntu session, the new folder immediately reflects the correct name.
Everything works as expected! A total win for both WSL2 and Deno.
Results of Initial Usage of Deno
The Deno docs are solid. The API is familiar to anyone who has used Node. Scripting with top-level await works and makes complex tasks a breeze. If you are interested in using the latex-to-text.ts Deno script, check it out here.
I like that Deno enables TypeScript by default, but it doesn't require everything to be typed. Effectively, you can script in plain JavaScript and add types as you see fit. There is also a ton of portability between Node packages and Deno. Overall, consider me impressed.
There are some additional issues around integrating VS Code with Deno, but all of the issues I found can be resolved in three short steps. First, install the justjavac.vscode-deno
extension to solve several problems, then install the deno-vscode
plugin which easily generates a deno project using solves all of them. I also vscode-deno-extensionpack
which includes the above extension plus other tools like Prettier.
The second thing to do is to can be resolved by installing deno-vscode, but that doesn't work in a Ubuntu WLS setup, where VS Code in the Windows layer cannot access Deno within the WLS subsystem. To obtain the same benefits manually, follow the instructions in this article.
The third step is to get VS Code to stop complaining about top-level await. This may be a TypeScript core issue. I created this GitHub issue to investigate that. Here's the workaround I can provide for my use case, but it may have side effects in larger projects with complex imports. My use case, as you recall, is a single .ts
file, so I don't have a problem doing this. I add \"isolatedModules\": true,
to my tsconfig.json file. This allows VS Code to stop complaining. Alternatively, I could just endure a false flag error from VS Code. Deno runs the code just fine invariant to the complaint from VS Code.
I've also been extremely impressed with Grammarly. I use both the paid online app and also the Chrome extension. I recommend it over Microsoft Word for spelling and grammar checking at this point.
Edit: 4/5, Hours After Original Publication
The Deno team has been incredibly responsive to multiple GitHub issues I created and they have already merged a pull request which fixed PowerShell installation. You can refer to the issue links above. After PowerShell installation, closing VS Code, closing open terminals, and reopening everything, git bash does have access to Deno.
While my exploration with WSL has been a ton of fun, it seems unnecessary for the purpose of deno usage, given the recent fixes. Moreover, WSL and Windows do not share a deno reference, so if you install in WSL and run VS Code in windows, you can't deno init
and some other important things. So WSL currently does not seem to be a best practice.