Sometimes Less is More
When it comes to software development tools, bigger is better.
Apparently.
Feature Bloat
Integrated Development Environments (IDEs) keep growing. Some of them have so many features I don’t even know all the things they can do.
The world in my window
High-end IDEs can display many different panels giving various views into system configuration settings, project directory tree, project configuration settings, various “consoles” and log files, and different kinds of source and data files. All or most of these panels can be enabled/disabled and expanded/contracted, and some appear automatically whenever the IDE thinks they should and not necessarily when we think they should.
The IDE window can become cluttered with panels and tabs within panels. When you try to grab the edge of a panel to shrink it, there’s a fair chance you’ll inadvertently touch a feature like a place marker or a breakpoint that is activated/deactivated by clicking in the gutter between panels, or hover over a point that causes a tooltip to block the area you’re trying to navigate to.
Here’s a screenshot from a Microsoft blog post dating from 2014, giving a preview of VisualStudio 2015 and Blend. The point isn’t to pick on VisualStudio, but only to illustrate how a typical modern IDE looks when it has several panels open. Other IDEs have the same characteristic.
In the illustration, the focus is clearly on the panel in the center of the window; it’s what the blog post is about, after all. But in general use, with four or more panels visible in the window, where is the developer supposed to be looking? Is it possible the other panels are distracting? How much screen real estate is available for the task the developer is engaged in at the moment?
As Nobutada says to Algren in the training scene in The Last Samurai: “Too many mind.”
Personally, I’m not convinced it’s a better “user experience” to have every tool represented within a single window than it is to have multiple windows open. That could come down to personal preferences.
In the illustration, the focus is clearly on the panel in the center of the window; it’s what the blog post is about, after all. But in general use, with four or more panels visible in the window, where is the developer supposed to be looking? Is it possible the other panels are distracting? How much screen real estate is available for the task the developer is engaged in at the moment?
As Nobutada says to Algren in the training scene in The Last Samurai: “Too many mind.”
Personally, I’m not convinced it’s a better “user experience” to have every tool represented within a single window than it is to have multiple windows open. That could come down to personal preferences.
If it’s worth doing, it’s worth overdoing
Some IDEs are equipped with embedded mini-apps (not an official term) to help you work with particular kinds of files. This is a mixed blessing. Often it’s more effective to edit the plain text of the file. Here’s the default view of a Maven POM as presented by Spring Tool Suite, an Eclipse-based IDE:
In fairness to the IDE developers, this mini-app encapsulates expert-system knowledge of Maven POMs. It analyzes the POM and calls out potential problems. That can be useful at times; after all, Maven POMs remain mysterious even after years of use. But most of the time we just need to edit the XML text. We aren’t asking the IDE to tell us what it thinks we should have written. The default view should be XML text with appropriate highlighting. To get there, you have to choose a different view of the POM; and the easiest way to do that is by using the mouse, which many developers consider a hindrance.
Popup madness
In keeping with the philosophy of overdoing things, some IDEs automatically pop up so many tooltips and reminder icons when you’re in an editor that you can’t even see the text you’re trying to modify. When you move the mouse pointer away to try and dismiss the tooltip, you’ll often inadvertently hover over another area that spawns a tooltip, unrelated to your immediate interest. When you know the language and the libraries well, this can really slow you down and kill your focus.
Here’s an example from JetBrains IntelliJ IDEA. The illustration captures sections of the screen as the developer moves the cursor across a line of source code.
Startup delay & periodic stalls
High-end IDEs need to collect a lot of information about the project in order to provide you with context-sensitive help while you work. While this may be helpful at times, you pay the price for it every time you use the IDE.
The more “advanced” the IDE, the longer it takes to start up as it “prepares the workspace,” “detects frameworks,” “indexes files,” searches online for available updates that you haven’t asked for, and who knows what else. From time to time during the day, the tool has to repeat these operations to refresh itself. It’s hard for developers to stay “in the zone” when the tool interrupts flow.
Complicated configuration
It can often take several minutes to locate the place where the IDE has hidden a particular configuration setting, opening each drop-down menu and context menu until we can find something that sounds as if it might be the configuration setting we’re looking for.
Even if we can work out which settings the IDE uses for a given Thing, as often as not the operating system is looking at different settings located elsewhere on the system to control the same Thing. Is the IDE using the same version of the compiler and libraries as the build tool when executed on the command line, or the CI server?
Modern IDEs are highly configurable. You can suppress the display of panels and editor tabs. You can ask it not to be quite so helpful while you’re editing files. The downside of all this configurability lies in figuring out how to change the configuration.
Of course Google is our friend, but unfortunately the “help” it locates for us rarely matches the actual behavior of the version of the IDE we’re looking at. “Simply* open the Foo menu, and…” only there’s no Foo menu “…or you can use the key sequence, Ctrl+Alt+M…” which does nothing at all, or something you didn’t want to do.
* A word to the wise: Don’t use the word “simply” when writing documentation or answering questions. It’s the Kiss of Death.
Product documentation is often hard to navigate. The “search” feature assumes you already know the exact terminology the IDE designers use to describe each feature. If you don’t search for that specific term, you won’t find the help. So we look for questions and answers in online forums. The problem is all the answers for previous versions of the product are out there, and it isn’t always easy to find the information that applies to the version you’re using.
The Good, the Bad, and the Ugly
Many developers like working in IDEs because of certain useful features, notably:
- Tight integration across different tools (editor, debugger, test runner, coverage, profiler, etc.)
- Ability to run and monitor external programs within the warm embrace of the IDE window (dependency manager, build utility, HTTP server, Web browser, mobile device emulator, terminal emulator, etc.)
- Help with editing: Language-aware syntax highlighting, automatic completion, intellisense, automatic indentation, insertion of boilerplate code snippets, delimiter matching, etc.
- Assistance with several basic refactorings
- Awareness of project meta-data
- Integration with version control systems
But most developers aren’t as enthusiastic about feature bloat, waiting for “indexing,” flakey behavior of embedded servers and other tools, sudden crashes, different configuration settings between the OS and IDE, visual distractions while editing, limited support for external programs (for instance, with respect to version control systems you can check out and check in, but little else), frequent switching between keyboard and mouse, and an ever-growing memory footprint that is often much larger than that of the application under development.
How are Developers Coping?
Developers are coping with IDE bloat in three main ways:
- (1) Running external programs externally
- (2) IDE configuration
- Defining and using key bindings to reduce or eliminate the need for the mouse
- Using IDE features to reduce visual clutter, such as disabling editor tabs and enabling some sort of “distraction-free” mode that closes most of the panels
- (3) Using text editors instead of IDEs
- Switching to “smart” text editors such as VSCode, Atom, or Sublime Text 3
- Returning to the configurable editors of the past such as Vim and Emacs
- Using cloud-based development environments
There are trade-offs with these alternatives.
Running external programs externally
Problems with memory bloat, hung servers, hard-to-find console and log output, and inconsistent OS vs. IDE configuration settings can be reduced or eliminated by ignoring the IDEs features for running external programs within the IDE window.
The trade-off here is that you have to open, position, and re-size multiple windows to get a usable arrangement of windows on the monitor(s) each time you start up your development platform. Once you get that in place, the development workflow can be almost as smooth and seamless as when you work entirely within an IDE window, but often with quicker perceived response time and fewer “surprises” such as hung servers or different outcomes from local and CI builds.
Key bindings
Key bindings are useful, but they aren’t always consistent across IDEs, including IDEs offered by the same vendor (JetBrains comes to mind), and they can conflict with OS key bindings as well as presenting challenges for external keyboards that don’t have all possible keys. In that sense, configuring your IDE to emphasize the keyboard can involve yet another level of configuration pain. Of course, once that’s done it’s done; it isn’t an ongoing burden.
Perhaps a more significant issue is the fact that keyboard “shortcuts” were an afterthought in the world of IDEs, which came to be in the era when everything was pointer-driven by design. Using a modern IDE in a keyboard-only way can be clumsy, sometimes requiring more fingers than you knew you had, or unusually broad palms to enable you to stretch a hand all the way across the keyboard. A crab-like evolutionary adaptation resulting in asymmetrical hands could be useful for a developer.
Even with a good set of key bindings in place, there are IDE operations that remain easier to perform with the pointer than with the keyboard; particularly navigation between panels and activation/deactivation of panels; so it isn’t necessarily feasible to eliminate the pointing device from your work flow altogether.
Reducing visual clutter
Enabling distraction-free modes, disabling editor tabs, and eliminating rarely-needed panels simplify the IDE window considerably and can enable a smoother development work flow. With some IDEs you may be able to turn off some of the tooltips and other pop-ups that distract more than assist.
But it strikes me that these options move us back toward editors and away from IDEs. The look and feel of the IDE becomes more and more editor-like as we remove more and more visual clutter.
Maybe that’s not coincidental.
Modern smart editors
Smart editors like Sublime Text 3, Atom, VSCode, and even simpler ones like Leafpad and Geany offer most of the functionality developers use most of the time. They have the same issue with respect to key bindings as IDEs have; they weren’t designed with a keyboard-centric work flow in mind. They lack features that may or may not be important depending on circumstances. In particular, editors generally have poor support or no support for:
- awareness of project meta-data – IDEs are usually specialized for a language and have built-in “knowledge” of the way projects in that language are usually structured; they “know” the relationships between different elements of a project, and can help ensure things are consistent throughout.
- intellisense – in-context help for completing statements with the method calls that are actually available at that point in the code; in some cases, assistance with entering method arguments of the right types; that’s a bit more than autocompletion, which may only fill in the missing characters in tokens that you’ve already used in the source file
- assisted refactoring – refactoring can be tedious and error-prone when done manually; developers appreciate the refactoring features offered by the best IDEs
Those features may or may not be of great significance to you. It will depend on how you like to work, how familiar you are with the programming language and its libraries, and how well-structured the code base already is.
Some languages benefit from IDE support
In my experience, the programming language makes a difference when it comes to knowledge of project structure and intellisense. A specialized language such as R might be much easier to use with the aid of a good IDE; in that case, RStudio. Working with JVM languages, it’s hard to imagine achieving a smooth work flow with Java, Kotlin, or Groovy without a good IDE.
On the other hand, the work flow with Clojure and Leiningen or Scala and sbt (also JVM languages) can be smoother and lighter-weight using just a text editor and a terminal emulator in a separate window.
For most other languages – Python, Ruby, Go, C/C++, JavaScript, shell languages, etc. – a text editor seems quite good enough. With the advent of VSCode, we don’t need to resort to VisualStudio (the bloatiest of the bloaty) to work with .NET languages anymore. The command-line build tools contain the “knowledge” of project meta-data in those cases (e.g., make, rake, npm, bundler, dotnet, sbt, gradle, maven, etc.).
Refactoring manually
The most significant trade-off (in my opinion) is the lack of assisted refactoring support. It may or may not be something you’re willing to trade away. For what it’s worth, I find myself using the following refactorings most often:
- Extract Method – very frequently
- Extract Constant – somewhat frequently
- Rename – somewhat frequently
- Pull Up – infrequently
- Extract Interface – infrequently
- Extract Class – very infrequently
But how big a trade-off is it, really? What do these refactorings entail when we do them by hand?
Extract Method amounts to cutting a few contiguous lines of text and pasting them elsewhere in the same source file, and then writing a one-line method call or function call at the point where the lines were cut. You then paste that line at all the other points in the file where the original code had been duplicated (if any). When you consider that (a) IDEs often don’t quite do the extract the way you want, and you have to do a little manual editing anyway, and (b) duplication isn’t usually exact, and you have to edit the code to produce a generalized version of the near-duplicate logic, this doesn’t seem like a high price to pay. Extract Method is the refactoring I use most frequently by far; if doing it by hand is easy, then the impact for all the remaining refactorings will be very small.
Extract Constant is the same basic pattern – copy some text out of a line and paste it elsewhere, type in the rest of the constant declaration, and modify the original line to refer to the new constant; then use the editor’s find/replace functionality to change the rest of the references in the source file. It’s more tedious than when using an IDE, but not horrendous.
Rename is used most often within the scope of a single source file. The editor’s find/replace functionality is sufficient. To rename directory-wide or project-wide, it’s easy enough to write a command using grep and sed (or equivalent utilities) and save it as a reusable script. Another small price to pay.
All the other refactorings are used so infrequently that the lack of built-in support in an editor is a non-issue.
Traditional configurable editors
The “modern” smart text editors still share one issue with IDEs, and that is they tend to emphasize using a pointing device. The old warhorses of software development, Emacs and Vim, were designed and built for keyboard usage with no concept of a mouse on the horizon. It’s easier to set up a keyboard-only configuration with these tools than with IDEs or contemporary smart editors.
To get the basic editing assistance features – autocompletion, syntax highlighting, delimiter matching, indentation, snippets – plugins are available for any language you’re likely to encounter. These tools offer a great deal of power in a small footprint and with few demands on system resources. Once you have the key bindings under your fingers, they’re the same for every language you program in; you don’t have to remember how to use a different IDE every time you work in a different language.
Cloud-based environments
An interesting option that hasn’t yet come into its own is to use a cloud-based development environment through a Web browser, with no editors or IDEs installed on your own system. Until now, most of these have been designed to support specialized development work. For example, IBM’s OpenWhisk editor is designed to support development aimed at the OpenWhisk cloud platform. Similarly, CodeSandbox.io supports Web front-end development in JavaScript using React, Vue, Angular, and Preact…and that’s all.
Cloud-based editors for general use are still at an early stage of development. One that I’ve found quite useful is Code Anywhere. It supports about 75 different programming languages. The editor and the surrounding ecosystem work quite well. However, you won’t find the feature set or customizability that you’ve come to enjoy in your favorite IDE on your own machine. It’s a trade-off that might work for you, depending on how you prefer to work and what you’re working on. You could do a lot of development work at a coffee shop using a PixelBook…depending.
Equipment cost
As software grows in size and resource usage, the hardware we need to run it grows in direct proportion. As I write this, laptops suitable for development work are priced approximately as follows (this post is not an official source of information on pricing). These machines, and many others, can comfortably run any number of bloated IDEs:
- Dell XPS 13 Developer Edition – the price displayed on the same web page varied from around $940 to around $1,550 within five minutes. They may be using some sort of data analytics to predict how much each prospective customer is willing to pay. Be alert! In any case, you’re paying somewhere in the neighborhood of $1,300 to get a 16GB machine with a 128GB SSD and Ubuntu Linux pre-installed. That’s a 13-inch, but as a developer you’re probably going to use an external monitor anyway; so that’s another $150-$250, give or take. So you’re looking at about $1,700 to $1,900 for a very nice development box.
- Toshiba Portege Z30-C-138 – The manufacturer’s suggested retail price is $1,530; I found the product for sale between $1,250 and $2,460, depending on retailer. It has 16GB RAM and a 512GB SSD at the higher end of the price range, with a 13.3″ screen. If we say about $2,000 plus another $200 for an external monitor, we’re looking at about $2,200. The machine comes with Windows installed; don’t take this as authoritative, but I’ve had good luck runing Linux on earlier versions of the Portege over the years.
- Lenovo Thinkpad E480 – with 16GB RAM, 1TB HDD, and 14″ screen it runs about $1,200 to $1,300. With an external monitor, around $1,550.
Let’s get small
In a couple of previous posts, I explored the feasibility of developing in a small virtual machine (512MB memory, 20GB storage) using just one text editor, NeoVim (an implementation of Vim). I found it quite easy to work with 35 different languages with that setup.
A custom VM per project
The experience started me thinking along the lines of “getting small.” No one really works with 35 languages at a time. Most of us only need a couple of languages for any given project. In view of the Works On My Machine problem, it’s a good idea to stand up a pristine environment tailored for each project.
So, why not spin up a VM and provision it with just the tools we need for a project? The VM could run locally under VMware (cross-platform), VirtualBox (cross-platform), or Hyper-V (Microsoft Windows 10).
Provisioning a template instance
I decided to experiment with creating “base” or “template” instances of OSes that could be provisioned quickly with support for different programming languages, and other necessary tools. That’s a work in progress, but so far I’ve got configuration scripts to prepare template instances based on five different Linux and Unix distros, so you can pick your flavor. These instances have the Openbox display manager and the NeoVim editor installed.
All the distros come with shell languages and C/C++ compilers, and the templates also have Python and Python3 installed because some of the NeoVim plugins require them. Most also have Ruby 2.4.4 installed, as I wanted to play with Chef while I was at it, and Chef requires that.
On top of that, you can add whatever compilers, testing tools, and NeoVim plugins make sense for any given development project. The resulting development environment will run quite nicely in a small memory footprint.
As I write this, I still haven’t scripted the provisioning of customized development environments based on those templates, but it’s an ongoing side project.
Why traditional editors?
Why NeoVim (or Emacs) instead of VSCode (or Sublime Text 3)? Well, a colleague of mine that I used to work with often emphasized the importance of developers being fluent at the keyboard. Excessive use of the mouse slows down the pace of coding and testing, and diverts attention from solving the problem at hand. So, I thought about setting up an environment with no mouse at all, using tools that would not cause us to “miss” having one. NeoVim was built around the keyboard, unlike IDEs that have keyboard shortcuts added as an afterthought.
Bare-bones window manager
The template development instances have Openbox as the default window manager. Openbox can open windows, but by default displays only a featureless black screen; everything it does is controlled by key bindings. With two or three windows open – a couple of terminal emulators and NeoVim – you can do just about any application software development work you can think of. And you have six ttys, so you could have multiple terminals and no windows at all, if you wanted to get really small.
Here’s a screenshot from a Raspberry Pi provisioned as described below. It’s running one of the template configurations, with Openbox hosting a Neovim window above, split into two panes to edit a bash script and the corresponding microtest script, and a terminal emulator window at the bottom.
Cheap hardware
What does that have to do with the cost of hardware? Well, if a development environment can run comfortably in a 512MB VM with a 20GB virtual hard drive, then it ought to run even more comfortably on a Raspberry Pi with 1GB memory and a 32GB micro-SD card. How would the cost of hardware compare with the developer laptops mentioned above?
- Raspberry Pi 3B+ kit with all the necessary bits included: $60 – $70.
- USB power cable extension with on/off switch: $0 – $7
- Low-end monitor: $15 – $60
- Low-end keyboard: $3 – $12
- USB mouse: $3 – $10
- Ethernet cable: $3 – $10
- Nifty NeoVim logo sticker: $4
Total price between $88 and $173. Cost of licenses for high-end IDEs or cloud subscriptions: $0. And you could dispense with the mouse and squeeze the cost down to $85. It isn’t needed for writing code; only for testing in GUI environments.
Of course, hardware cost isn’t the greatest cost involved in software development. However, there are other costs that are becoming more important as climate change and resource exhaustion take hold. A Raspberry Pi certainly consumes less energy than a conventional desktop or laptop computer. And when the time comes to dispose of or recycle the material, there’s considerably less material to dispose of or recycle.
Enough talk
Here’s what we’re going to do:
- Assemble a cheap machine
- Install a minimal OS
- Install minimal development tools
- Add support to the environment for a representative category of application development
You can try this project from Github to build a Raspberry Pi and configure it as a base environment for lightweight development: bootstrap-raspbian-jessie-dev-base. Once you have the unit assembled and Raspbian Jessie installed, the bootstrap script from the Github project will perform some installs and configuration.
I hope you will actually do this and not just skim over it. I believe an abstract understanding of a topic is useful, but when augmented by gut-level understanding it’s even better.
Provisioning for “Real” Development
The base provisioning sets up the unit as a lightweight development environment. You then have to add whatever tools you need to work on the language(s) you need to work on. The details will vary considerably depending on the work you need to do, but it typically includes resources like these:
- compilers
- build utilities
- dependency managers
- testing tools
- plugins for the NeoVim editor
- databases (maybe)
- HTTP server (maybe)
Not all tools install with apt on a Pi because not all packages are available in binary form for the ARM architecture. Some languages are easier to set up than others. To provide a realistic example here, rather than a deceptively simple one, let’s flesh out the configuration to support the following sort of development work:
- Services written in Ruby, presenting a RESTful API and accessing a relational database
- Browser-based single-page front-end app as a client of the services
- Automated checking at the unit, API, and UI levels
That’s only one possible stack among many, but it’s a fairly realistic example. A lot of developers work on applications using these or similar technologies. You’ll have to do similar things for the technologies you work with, too, so you might want to try this yourself or at least read through it.
We’ll need to install the following tools (other choices are possible, of course):
- Ruby
- Ruby language support
- Bundler (dependency manager, build utility)
- Sinatra (web framework suitable for RESTful services)
- Rspec (behavior-oriented spec framework)
- Cucumber (behavior-oriented UI checking)
- HTTP server
- Thin (lightweight HTTP server suitable for dev/test)
- Node.js (HTTP server support for the front-end app)
- Relational database system
- Sqlite3 (relational database suitable for dev/test)
- JavaScript language support
- Node (JavaScript environment & execution)
- NPM (dependency manager, build utility)
- React (single-page app support)
- Jasmine (behavior-oriented spec framework)
- NeoVim plugins
- vim-ruby/vim-ruby (Ruby editing support)
- pangloss/vim-javascript (JavaScript editing support)
Ruby-Related Installs
Ruby language support
As this was written, you could install Ruby 2.1.x on a Pi with apt, but the current version was 2.5. Fortunately, we’re not the first to have this need, and there’s help to be found online.
Let’s run a script by Tom Black to install rbenv and ruby 2.5 on the Pi. This installation doesn’t depend on an ARM binary, as it builds Ruby from source. That means it takes some time to run.
Tom captures the run time in his script so we can see how long it takes. In my case, on a Pi 3B+, the build took 15 minutes and 47 seconds.
After the script completed, I had to source my .bashrc file to cause the rbenv init command to run.
. .bashrc
After that, I ran ‘rbenv versions’ to see a list of the Ruby versions rbenv knew were installed.
rbenv versions
The command returned only version 2.5.1. The command:
ruby --version
also returned 2.5.1.
Bundler
Bundler is a widely-used dependency manager and build utility for Ruby. It is distributed as a Ruby gem.
To double-check that the desired version of Ruby is in effect before installing gems, you can use this command:
gem env home
In my case, it was pointing to version 2.5.1 under user ‘pi’, which was correct. At this point you can install gems in the usual way. I installed Bundler like this:
gem install bundler
and it worked fine.
Additional gems
Additional gems, including Sinatra, Rspec, and Cucumber, will be installed by Bundler in the context of building the project.
JavaScript Language Support
Node
The Pi comes with a surprising number of development tools already installed. Let’s check the version of Node that’s in place.
node -v
In my case, that reported v4.8.2. As of the time of writing, Node was into the 9’s.
Like Ruby, the Pi comes with Node installed, but not the current version. Also like Ruby, others have had the need to install a current version of Node on a Pi, and have published help we can use. We’ll try Richard Stanley’s install script:
wget -O - https://raw.githubusercontent.com/audstanley/NodeJs-Raspberry-Pi/master/Install-Node.sh | sudo bash
That ran quickly and with no problems, and afterward ‘node -v’ reported version 9.11.1.
NPM
NPM is a dependency manager and build utility for Node. In my case it was already installed on the Pi…and it was the current version!
React
We need the react and react-dom packages. These are Node packages and not Linux packages, so we install them with npm:
npm install react react-dom
Jasmine
For micro- and unit- level automated checking, we want to use Jasmine:
npm install jasmine
Sqlite3 Relational Database
Sqlite3 is not generally considered suitable for production, but it’s commonly used for development. I installed it with:
sudo apt install sqlite3
I encountered no problems, but you should be aware there are several reports on the Raspberry Pi forums and StackExchange of errors when installing. Don’t worry if you do get errors, as solutions are available. It’s possible these errors have been corrected since those issues were reported.
NeoVim Plugins and Configuration
NeoVim Ruby support
The bootstrap script to provision the Pi as a base development environment included the installation of NeoVim plugins for editing Ruby source. That’s because on several of the other environments I used Chef to handle some of the provisioning, and Chef requires Ruby 2.4 or later. Chef was not used in the Pi version of the bootstrap script, but the installation of NeoVim plugins was still in place.
To check this, I started NeoVim and entered some Ruby source code. I observed that syntax highlighting and indentation were working as expected. I didn’t have autocompletion support installed, so I didn’t expect it to happen.
NeoVim JavaScript plugins and configuration
Numerous JavaScript plugins are available for NeoVim. For now, we’ll install the one from pangloss.
git clone https://github.com/pangloss/vim-javascript ~/.config/nvim/bundle/vim-javascript
Conclusions
We won’t develop an app here. The point was to demonstrate the general level of effort involved in setting up a Raspberry Pi to do “real” development work with a lightweight tool stack…no IDEs, just one editor plus whatever software is needed for testing and deployment. At this point we have all the tools we need to work on a microservices app in Ruby that’s front-ended by a React app.
The key take-away is that to complete the provisioning of a lightweight Linux instance to support any given programming language you will probably find some steps are very easy and others are more tedious.
I don’t want to oversell this as a simple thing to do, but I do think it can be a useful setup for many types of application development, and it solves or mitigates some of the problems that are on the rise as a consequence of the increasing complexity of IDEs.
In my opinion this also demonstrates we don’t absolutely need an expensive machine to build an effective and usable development workstation. That may not be true for all types of development, but it appears to be true for most mainstream application development work. I feel confident I could handle just about any development project using the Pi I just built, augmented with cloud-based static code analysis, continuous integration, deployment, and hosting services.
Who might care?
I can think of at least two broad groups of people who might be interested in this sort of setup.
Developers stuck with heavy tools
First, there are developers who may feel “stuck” with heavyweight tools because they’re working on legacy systems for which development has “always been done that way.” Consider:
- .NET development with VisualStudio on Microsoft Windows. This sort of work can be done quite nicely on a small-footprint Linux instance using tools like NeoVim, Emacs, or VSCode. The command-line tool ‘dotnet’ encapsulates all the necessary knowledge about .NET project structure, package management, and builds; a heavyweight IDE is not needed to support development on this stack. FWIW, I’ve met people who work at Microsoft who closed VisualStudio for the last time once they got a taste of VSCode, with no regrets.
- COBOL development targeted to an IBM mainframe environment. This sort of work is typically done with (a) OEDIT on the mainframe itself, (b) IBM Rational Developer, involving a heavy IDE on Microsoft Windows talking to one or more additional servers (Greenhat, RD&T), or (c) Compuware Topaz Workbench, a heavy Eclipse-based IDE that has to have a live connection to a mainframe to support all its features. This work can be done in a lighter-weight fashion on a Linux instance using GnuCOBOL, with help from tools like Cobol Unit Test and BerkeleyDB. A moderate scripting effort can wrap FTP commands to transfer source and copybook files between the development instance and the mainframe. The lightweight setup is suitable for the bottom layers of the “test automation pyramid” using a TDD work flow.
- Oracle JDeveloper for Java applications. Text editors are not ideally suited to working with Java; a good Java-aware IDE provides better support for this type of work, in large part because the directory structure has to reflect package structure and text editors can’t provide any assistance navigating around the project files. It’s also nice to have under-the-covers management of the Java classpath. But JDeveloper swings the pendulum too far the other way; it can take upwards of five minutes for a local build to run, which makes it hard to maintain focus with short red-green-refactor cycles. A lightweight Linux instance can host an IDE like JetBrains IntelliJ IDEA or Eclipse, providing a much smoother work flow than JDeveloper.
Marginalized people looking to advance
The second group who might be interested in this are those who are shut out of opportunities due to the cost of resources. This could include public schools, which are chronically underfunded and often depend on the generosity of corporations, as well as the marginalized or underprivileged, and young people in developing countries who want to learn software development to prepare themselves for the future but who can’t afford $2,000 laptops and $1,000 annual subscription fees for tools and services.
Very usable and robust development machines (not to mention web servers, database servers, wireless access points, routers, firewalls, and you-name-it) can be assembled from inexpensive single-board computers and used peripherals. There are effectively no limits to what people can create using such resources. It comes down to their imagination and determination.
Wrapping Up
I undertook this exercise to find out whether it was feasible to do “real work” without any “heavy” IDEs in the picture. It was a reaction to the seemingly excessive bloat in IDE products, which (in my opinion) were already functional enough to be useful many years ago, and didn’t need more and more and more features. I wouldn’t resort to a text editor for all types of development; there are plenty of situations in which an IDE offers good value. But I learned that very modest tooling is all we really need for most of our work.
If you agree with my colleague Junilu that using the mouse with an IDE slows you down, then you might actually prefer a setup like the one described here. Vim and Emacs make mouseless use feel normal and comfortable. Removing the mouse from an IDE creates speed-bumps and dead-ends that impede flow, notwithstanding the ability to define keyboard shortcuts. Those tools weren’t designed to be used that way. Vim and Emacs were.
Comment (1)
Bob Chesley
The best overview of editors and IDEs I have seen recently. I too keep one foot in the management camp and one on the technical side and currently use VSCode, WebStorm, IntelliJ, and vi+-m.