Fun/Learning

One can build impressive things with JavaScript. It has evolved into a rich ecosystem of tools and libraries that give developers a lot of power. With this comes an impressive amount of choice and the resulting cognitive load when designing projects that use it is potentially daunting. The feeling commonly known as “JavaScript fatigue” has been felt by many members of our team. We’d like to shield our contributors from this.

Whilst I’m biased as one of the stronger proponents of Swift in our team, we’d come to appreciate the elegance of Swift, its core libraries and the good design it encourages.

As with all HaC projects, part of the goal of this website is for contributors to learn something new and have some fun. We knew most any contributor could learn more about the state of server-side Swift and we were pretty sure we were going to have some fun with this.

Contribution

As server-side Swift is in its infancy, we saw an opportunity to play with something that not many people have played with. We have run into bugs and limitations of Swift along the way and while this is at the very least a learning experience for us, we hope that we can contribute some of our learning and solutions to the community.

Power

It was clear from the beginning that we had big ambitions for this little project. We had dozens of concepts for what we could do with it.

Swift is a general-purpose language with a relatively expressive static type system and some really natural-feeling data modelling features. It has been designed from the ground up with modern programming in mind. It combines many emerging patterns and features from other programming languages such as optionals, generics and powerful enumerations whilst leading the industry with its opinions on protocol-oriented programming.

Swift gives us the power to quickly write readable implementations of our bags full of feature ideas.

Downsides

Lack of Code sharing

An issue I have so far ignored, and probably the biggest bottleneck at the moment in making Swift an option for larger-scale web projects, is that Swift doesn’t run in the browser. Javascript has this benefit of being able to run on both the server and the client. That’s a really compelling feature. Swift only gets this benefit when we’re talking about native iOS apps (though there are certainly people interested in Swift running in the browser, see this post).

What this means in practice is that we either reimplement some functionality on both the backend and frontend for the sake of interactivity (e.g. Form validation) or we sacrifice interactivity for the sake of keeping code in one place. Neither is a particularly satisfying solution.

Tooling/Libraries

JavaScript has a vast community behind it pumping out new tools and libraries at an impressive rate. Swift doesn’t quite match the volume of libraries and the body of support available in the Javascript world. Here’s a few places where we found the tools/libraries lacking:

Cross platform support (there are some discrepencies between macOS and Linux Swift behaviour)

Interaction with .env files

files Fast continuous deployment (our deployments using existing Heroku Buildpacks take >10 minutes)

Mature web frameworks (there’s still a lot of work to be done even in the most popular offerings)

Stable package management

Nice front-end development experience (see below!)

Typesafe templating (see below!)

It was common to find libraries that did what we wanted but that only catered to iOS/macOS. More and more cross-platforms packages are being made available and you can browse these using IBM’s ad-hoc package catalog (UPDATE Jan 18: Package Catalog has been deprecated).

With all that said, we decided that, for us and for this project, the downsides here were merely interesting hurdles and that we were going to run with Swift on the backend.

What we’ve done so far

An ergonomic development environment

Swift hasn’t stopped us from using all the tools we know and love from a ‘normal’ web development setup. To go from nothing to having the website built and loaded on your machine is as easy as:



$ cd hac-website

$ docker-compose up

$ open http://localhost:3000 $ git clone https://github.com/hackersatcambridge/hac-website $ cd hac-website$ docker-compose up$ open http://localhost:3000

We use Gulp to watch for changes to our Swift files, rebuild the site, and reload the browser.

We spit out the build errors on the page itself so we don’t have to go fishing in the console for error messages.

Some handy error messages that our debug build shows on the page for us

Check out our gulpfile to see how we got this working.

A Type-safe HTML Builder

Whilst we were enjoying the benefits of a static type system for the internal logic of our website, when it came to display logic we were turning to Stencil. Stencil is a templating language for Swift that allows you to pass a roughly HTML-like template and a pile of values to the renderer and it will either spit out a rendered page or a nasty error. We were breaking these templates all the time. What’s more, without a statically defined interface to these templates it was difficult to reuse them in any robust manner.

Towards solving this problem, we’re experimenting with making a Swift HTML Builder that allows us to create type-safe templates. Here’s a real-world example of what writing a View Model in this system looks like:

An `ImageHero` component that renders a featured image

We’ll be discussing this system, what it does, and why it’s beneficial in much more detail in the future.

Conclusion

Of course, a trade-off exists between having fun and building something to last. As a student society website, this is never going to be a large-scale system but it is one that needs to survive many handovers to new teams. Although it’d be unreasonable to expect many of our potential contributors to have significant server-side Swift experience, and we will stop short of recommending Swift for any large-scale web project for now, I think this project is a good place for exposing new technologies to contributors.

I’ve never had as much fun working on a website as I am with this stack. The use of Swift along with our (loose) MVVM pattern, a statically-typed HTML builder and adherence to a BEM CSS pattern has made for what I consider a very sober development experience and a wonderfully modular structure. The lessons I’ve learnt from this setup are ones that I’ll carry with me to future projects and ones that I look forward to sharing with contributors to the website.

Links and further reading