Software, as Marc Andreessen says, is eating the world. Everything we do is mediated through someone’s code -- running on a smart thermostat, a smartphone, the old familiar PC, or as a microservice in an ever-expanding cloud.

We’re finally delivering on the decades-old promise of a ubiquitous computing world. But more than that, from the developer's standpoint, the tools available to us are better and more sophisticated than ever. We’re also seeing monolithic applications break apart into services and platforms, ready to become part of your applications.

At the heart of the current wave of change are new design patterns suited to a highly distributed, asynchronous computing world. Yes, we’re still building n-tier MVC and MVVM apps -- and we’ll carry on building them for a long time to come. But new microservice-focused design patterns give us a new set of tools to help us build highly scalable, concurrent applications that can handle the eventual consistency that comes from working with asynchronous services.

Languages like Erlang embody many of these principles, as do PaaS tools such as AWS’s Lambda or Microsoft Azure’s Service Fabric. You can also roll your own actor-based microservices using the open source MQTT messaging framework and the Seneca microservice toolkit for Node.js. Microservices are ideal for implementing actors, as they are at heart switching engines that take in inputs, process them appropriately, then send the results on to other services.

That’s why Node.js is one of the more important technologies underpinning modern software: It gives you that switching engine, with deep support for REST and JSON APIs. Node.js offers a cross-platform environment, too, with support for most common operating systems (and soon with a choice of JavaScript engines). As JavaScript moves to a yearly update cycle via ECMAScript, there’s additional scope for rapid evolution and support for new language constructs coming from JavaScript-derived languages like Google’s Dart and Microsoft’s TypeScript.

Node.js is only one example. The darling of disruptive technologies, Docker, was developed using Google's Go, a modern systems language from some of the same developers who originally created C. Like many new languages, Go has features that are designed to help manage concurrency and to support parallel computation, helping developers take advantage of current processor architectures as well as distributed computing models.

Let's not forget the cross-platform tools and frameworks that make it easy to build apps that run on, well, nearly anything. Some, like Apache’s Cordova, are hybrid HTML environments that use a runtime to deliver near-native performance. Others, like Xamarin, provide tooling that compiles familiar code into native applications on multiple OSes, while others like the iOS and Java tooling built into Microsoft’s Visual Studio make it easier to manage your code in a single environment and a single project.

Even the infrastructure on which all this runs has become software defined. IaaS has become the foundation of the modern application platform, with containers becoming a key deployment mechanism. Tools like Jenkins automate build and test processes, and they increasingly integrate with familiar IDEs. Existing build tooling is also being extended to support these scenarios, as well as offering cross-platform builds. Microsoft’s Visual Studio Team Services implements the company’s new build tooling, with support for delivering code to Apple hardware for iOS builds.

At the same time, configuration management tooling makes it possible to programmatically manage your underlying infrastructure and manage those descriptions through your source control services. We live in a world where you can inject a Chef agent into an Azure VM that’s created from a recipe that’s stored in a GitHub repository. The shift to devops is changing the way we think about both software and hardware.

Combining software-defined infrastructure with modern build and deployment technologies, as well as with the cloud, makes a lot of sense. It also changes the end state of a build. I recently spoke to a major U.K. consumer service that does a build weekly, and as part of the process delivers its entire virtual infrastructure -- switching IP addresses between the new build and the current service once testing is complete (and keeping the old infrastructure in place as a backup in case of problems).

That’s where containers come in to play. They encapsulate services and application components, providing a means to deliver isolated units of an application and deploy them quickly onto physical and virtual servers. Container technologies like Docker are able to work with thinner, more focused server OSes such as CoreOS, helping to reduce risk by offering smaller attack surfaces and increased process isolation.

It’s not only born-in-the-cloud services that take advantage of these new technologies and approaches. Some of the most enthusiastic adopters are organizations that have a very conservative IT history, including government bodies. One U.K. government agency has shifted to do a service push every three weeks, using tools like Ansible to help manage applications and servers.

The other side of the story is an explosion in development tools and services. New programmers’ editors like GitHub’s Atom and Microsoft’s Visual Studio Code make it easy to start programming fast and enable you to use common frameworks, development platforms, languages, and even documentation services.

There’s never been more choice for developers of all skill levels in languages, tools, services, and platforms. If you want to build a modern app, pick a technology that seems right for your project -- and start writing code.

Author of InfoWorld's Enterprise Microsoft blog, Simon Bisson has worked in academic and telecoms research, been the CTO of a startup, run the technical side of UK Online, and done consultancy and technology strategy.