Apple M1: A Javascript Engineer's Review

January 18 2021 | words: 1342 | time to read: 6 min

As an Apple nerd, I’ve been anticipating Apple’s line of Apple Silicion (ARM-based) Macs for a while. The transition to ARM was announced at WWDC 2020, with the first Macs shipping with the chips announced at an event in November 2020. The first three computers Apple announced are their least powerful: the Macbook Air, the 13” Macbook Pro and the Mac Mini. Initially, I wrote this first line of Apple Silicons Macs as computers that looked good, but ultimately weren’t for me. Something as light weight as the Air wouldn’t satisfy my obviously “Pro” needs. I’m a Software Engineer for god’s sake! I need the biggest screen and most powerful CPU available. Not to mention, taking the plunge into Apple Silicon on its first generation for a primary work machine felt like a huge risk. Given how much I rely on my laptop, I decided to give these machines a miss. I’d take another look once the more powerful Macs were updated and the ecosystem had been given some time to catch up.

Fast-forward to late December 2020 and I still couldn’t shake the idea that perhaps this Macbook Air would be the perfect machine for me. These new Macbook Airs had been in the wild for a few weeks and I’d read all the reviews. It seemed as though reviewers were unanimously blown away by the performance of this machine. Benchmarks were reporting that, in single-core performance, these M1 Macs outperformed every Mac Apple had shipped previously. As John Gruber of Daring Fireball put it:

…they are astonishingly good — you must acknowledge that certain longstanding assumptions about how computers should be designed, about what makes a better computer better, about what good computers need, are wrong.

What if I was wrong about needing the biggest and the best Apple had to offer? What if these new CPUs were so good that I could now be even more productive on a Macbook Air than my 15” Macbook Pro? Let’s talk about that Macbook Pro…

For the last four years I’ve been using a 2016 15” Macbook Pro. For the most part, this computer has been fine, but I always felt that the introduction of both the Touch Bar and the Butterfly Keyboard where a step backwards. A change for the sake of change rather than something that added real value. The keyboard in particular was the reason for two seperate visits to the Genius Bar over the course of this laptop’s life. Each time, I had to be without my laptop for a week as it was serviced. I also never really got used to the lack of a physical escape key. As a software engineer, I use that key a lot. It never felt quite the same smushing my finger up against a piece of glass. I put up with those quirks because at its core this was still a powerful computer that handled everything I threw at it.

In the last few months, it started feeling a little more sluggish. Not slow by any means, but builds were taking a little longer than I would like to complete. COVID has changed my work habits a little which also meant that I felt like I wasn’t getting value out of having a large laptop. When I’m working from home, I’m usually working on my 27” iMac (which I love) and when I’m in the office my laptop is generally always connected to an external display. When I am using the laptop’s display, it’s mostly in meetings while I’m taking notes or sharing presentations. I’ve also been cycling (a fair distance) into the office to try and avoid public transport, so I’m always on the lookout for ways I can lighten that load. All of these factors combined started to make the M1 Macbook Air a very attractive option.

However, given the shift to a new architecture, there was a big question mark around whether or not this machine could actually do what I needed it to do. If there was a piece of mission critical software that was broken, it would be an immediate no-go. There was also the question of performance. If most of the tools I need are running under Rosetta, would I really be getting the full value out of this new machine? There was only one way to find out, so I headed over to the Apple Store and picked up a M1 Macbook Air with 8GB of RAM (in silver, if that’s interesting to you) and got to work setting up everything that I needed.

At work, I rely on a pretty common stack of tools and services. Our front end and back end are both written in Typescript. The front end is a React app and the back end is Serverless. We make heavy use of Lerna, Yarn and Jest across both projects. For the back end we also use Docker and the AWS CLI. The first hurdle I had to jump over was Homebrew. I knew that Homebrew did not yet have a reliable Apple Silicion version, so I was banking on installing it under Rosetta, which worked fine. Once Homebrew was installed, I pointed it to my Brewfile that I use whenever setting up a new computer and it ran through that more or less as expected. It installed Apple Silicon versions for tools where available. The only tool that didn’t install from my Brewfile was VirtualBox, which was expected. I also installed the Docker Desktop Tech Preview, which also seemed to work as expected.

I hit the first (and only) hurdle when trying to use aws-cli to retrieve some files from S3 (part of our test workflow). Every time I tried, it would fail with an error referring to an illegal hardware instruction. Uh-oh. Of course something fairly minor like this would be the reason I couldn’t use Apple Silicon! After an hour or so of googling, it turns out the error was actually caused by an unsupported Python version (that I’m assuming was installed as part of XCode’s developer tools). Given that Python 3.9.1 supports Apple Silicon, I ran brew install python@3.9 which installed the latest version and appears to have resolved the issue with aws-cli. With this issue resolved, I was able to get both our projects building, testing and running without issue. I immediately felt a pretty distinct performance improvement over my Macbook Pro. I was interested to know exactly how much of an improvement, so I got to benchmarking:

Front end Benchmarks

- yarn clean && yarn build
	- iMac (2020): 122 seconds
	- Macbook Pro (2016): 212 seconds
	- Macbook Air (M1, 2020): 137 seconds
- yarn test (~1800 tests)
	- iMac (2020): 44 seconds
	- Macbook Pro (2016): 143 seconds
	- Macbook Air (M1, 2020): 123 seconds

One important thing to note was that running our front-end tests, I was bumping up against the 8GB RAM this machine had, and the tests slowed down significantly once it started to write to swap. I imagine the yarn test numbers for the Macbook Air would be significantly improved on a 16GB machine.

Back end Benchmarks

- yarn clean && yarn build
	- iMac (2020): 66s
	- Macbook Pro (2016): 133s
	- Macbook Air (M1, 2020): 105s
- yarn test (~n tests)
	- iMac (2020): 85s
	- Macbook Pro (2016): 138s
	- Macbook Air (M1, 2020): 108s

Across both my front end and back end workloads the Macbook Air was about 40% faster than my Macbook Pro. This is made more impressive by the fact that this thing doesn’t get hot at all and has better battery life than my Macbook Pro. Remember what I was saying about long-held assumptions about trade offs no longer applying?

I’m happy to report that I’m switching from 2016 Macbook Pro to the M1 Macbook Air. Given that I think this machine has legs, I returned my 8GB model and ordered a 16GB one. As I mentioned above, I felt a little constrained by the 8GB of RAM.

I’m blown away by what Apple has been able to achieve here. The fact that only a few months after announcing an architecture transition an engineer such as myself can fully make the switch is incredible. People have made a lot of noise about the M1 which is totally justified, but Rosetta 2 is a technical marvel that goes a long way towards mitigating my concerns about switching. I’m excited for what this means for the future of Apple’s Macs especially for their machines such as the iMac where they aren’t as constrained from the perspective of power and thermals.