Cloud Functions for Firebase with Compiled Code
📚 ES6, ES7, Babel, Flow, TypeScript & ParcelJS
There are many reasons to compile your Cloud Function code:
- Types! TypeScript, Flow, ReasonML or another language for typing.
- Use new JS features not supported by the Node 6 or Node 8 runtimes.
Here we will explore HOW we can set up our project and some pros/cons of the available methods. If you want code examples, see the links at the end.

Complexities of Compiling Code
- you are no longer deploying your raw source code. You need to add compilation support into all your scripts and generate sourcemaps.
- you’ll likely want file watchers, which can be fickle depending on the setup. For example, TS requires the use of an external lib like
tsc-watch
orparcel-bundler
to add file watching support. - misc lack of library support. For example,
firebase-functions-test
is written in TS, so only has types for TS. - the Firebase Emulator does not seem to support file watching at this time, so you must rerun the
firebase serve
commands. - the Firebase Emulator only runs on Node 6 (at the time of writing), so if you want local emulation you must use Node 6 locally.
Compilation Script Options
npm package.json
scripts, .js
files & .sh
files are the usual suspects. Firebase does support some pre-/post-deploy hooks, but I would recommend keeping ALL scripts in one place, package.json
, and calling out to .js
or .sh
scripts if it gets too cluttered or complex.
Compilation Tools
Cloud Functions run on either (at time of writing, check links for current) Node 6.14.0 or Node 8.11.1 runtimes. Ideally, the code would be compiled to these exact targets (depending on which you choose to use), but this gets tricky depending on which tools you use:
- Babel: supports targeting exact Node.js versions via
@babel/preset-env
📚 Babel & preset-env
Compile to environments, not specifications - TypeScript: only supports targeting versions of the ECMAScript standard. This means you need to determine which ES version features are supported by which version of Node.js runtime, a bit annoying.
- ReasonML, and by extension BuckleScript, just compile to ES5, which is also not ideal, but at least you don’t need to investigate as both run on Node 6 or Node 8.
Adding these tools to can bloat our configuration and it can start to get overwhelming, especially when adding more asset types. Thankfully, package/application bundlers can give us the same tool support and centralise most of the configuration.
ParcelJS is a favourite as it has smart defaults and no (little) configuration.
Conclusion
Compiling your Cloud Function code increases the
- accessibility: more languages can be used.
- quality: types improve tooling and catching some errors earlier.
- longevity: new language feature support without changing the underlying infrastructure/runtime.
but also impacts
- complexity: the tool chain grows immensely once you delve into the compile-to-JS world. Learning and understanding the tools and how they may conflict adds quite a load.
- configuration: more tools requires more configuration.
I believe it to be worth the investment and would recommend following these rules:
- keep your scripts in a single place. Either directly in your package.json scripts or in external files executed by your package.json scripts.
- target the Cloud Function runtime you use (where possible).
- use a bundler to simplify the setup and improve the developer experience.
Explore your options with these examples
Part 1: 💻 Cloud Functions for Firebase with Babel, Flow & TypeScript
Part 2: 💻 Cloud Functions for Firebase with Flow, TypeScript & ReasonML via ParcelJS
Need something else to read?
More by me:
📑 Table of Contents
An index post for my Medium Series
💬 State of Firebase (late 2018)
2018 Releases & Improvements
If you found this useful, please recommend and share with your friends & colleagues.