Electron Dev Tool

There comes a time in every project when there becomes way too many commands and links to remember. I experienced this myself recently with Shindig.

This project consisted of a Meteor app, a Neo4j graph database, a Mongo database, hosted on Digital Ocean, with Kadira performance monitoring, Google Analytics, Heap Analytics, Facebook Auth, and Google Places API along with Android and iOS apps using Cordova.

All of these features come with baggage like API keys, dashboards, settings, pricing plans, documentation, and command line interfaces. This is quite a handful to keep track of so I compiled a bunch of notes so I could remember how do things like connect a local instance of the app to the production database for quality assurance.

I had so many notes that it this became an big annoyance for me to scroll through my notes and copy paste commands and keys everywhere. What I wanted was a simple UI — just some simple widgets to run these commands. And that’s why I created Dev Tool.

I used this project as an opportunity to check out Electron. Electron is an open source project that runs a local Node.js server inside Chromium (the open source part of Google Chrome) along with a Web UI. It sounds kind of janky, but it works pretty well. The Atom code editor (open source and supported by Github) is built on Electron, and Facebook’s Nuclide code editor is built on Atom. So I’m not too worried about this being a dead-end.

Electron comes with a basic inter-process-communication (IPC) API, so I made a simple wrapper to create remote procedure calls (RPC) by attaching a unique id to each request. Then I created some nice higher-order React components for building the UI with associated shell commands. The result is surprisingly easy way to build a simple dashboard for running shell commands!

Here’s the UI I build for Shindig in about 5-10 minutes.

Building your own dev tool app couldn’t be easier. You need to have a Mac, and I’ve tailored the commands to work with iTerm2 (e.g. opening up a new Tab). To install iTerm2 if you haven’t already:

brew cask install iterm2

Then you just need to clone the repo, install some dependencies, and you’re good to go!

git clone https://github.com/ccorcos/dev-tool
cd dev-tool
npm install

I also use trash for safely deleting files in some of the shell commands, so go ahead and grab that as well.

brew install trash

To start the app:


And to build a distributable standalone build:


And there you have it! The demo app gives examples for how to use each of the higher-order components I’ve built, and I’ll explain them to you now.

There are currently 6 core components that compose really well to handle all of the typical things you might want from a dev-tool.

The RunBtn will run a command in a new iTerm2 tab.

RunBtn("Node REPL", "cd ~; node;")

The ExecBtn will run a command silently.

ExecBtn("say hi", "say hello `whoami`")

Exec will run a command and call back with the results to render with.

Exec("whoami", (name) => {
return <span>Welcome {name}</div>

There’s a simple Text input component:

Text({placeholder: 'shell command'}, (cmd) => {
return RunBtn('Run', cmd)

And a Path component with autocompletion:

Path({placeholder: '~/path/to/file'}, (path) => {
return ExecBtn('open', `open ${path}`)

And a Select component to select options:

Select(['Desktop', 'Documents'], (selection) => {
return ExecBtn('Open Folder', `open ~/${selection}`)

The beauty of this design is that these components compose very concisely into pretty much whatever you want. The following will look up files on your Desktop, parse the string, and create a dropdown menu to select which file you want to open.

Exec('ls -1 ~/Desktop/', (result) => {
const files = R.pipe(
return Select(files, (selected) => {
return ExecBtn("Open", `open ~/Desktop/${selected}`)

Hopefully this project will prove useful to people. I hope to eventually build this into a generic Dev Tool app that can be configured with a JavaScript file to make it trivial to create user interfaces for our software project tools. And if that tickles your fancy, by all means, submit a PR!