I've written a lot of applications in PHP over the last 10 years, probably over 30 commercial and open-source projects. Some are used by hundreds of thousands of developers, others by millions via websites or web applications. So I had designed most of my career around PHP. Until now.

To compare the two languages and platforms, you have to apply several scales. On the one hand it is important to look at the language features themselves, and on the other hand it is important to see the topic through the eyes of a company: where is the market going and where are the costs lurking?

Disclaimer: This is an opinion driven blog post, which involves a lot of personal experiences in Germany that might not (at all) be true in your region or your life.

TL;DR: Why TypeScript will displace PHP

  • Economic reasons: Companies save money by having less diverse teams.
  • TypeScript has the better and faster evolving language.
  • TypeScript/JavaScript together with NodeJS has the bigger and more active community.
  • You are currently better paid as full-stack TypeScript (backend & frontend) developer.

The economy

The market demands more and more complex web applications. Where it used to be sufficient to use two knocked together jQuery plugins on your website, it is now indispensable to work in the frontend with larger and more complex frameworks such as React or Angular. This is not because jQuery is bad, but because customers are demanding more and more, that jQuery and other low-level frameworks are not able to implement economically in high quality. Once understood, frameworks such as React or Angular allow to massively increase the developer's productivity, and thus increase the income and fun at work.

Two technology stacks become one

A few years ago there were two standard technology stacks: The backend, which was mostly written in Java or PHP and delivered data via JSON or HTML, and the frontend, which was mostly written in Javascript.

That was urgently necessary, because neither Javascript ran well in the backend at that time (NodeJS was experimental and there were few backend libraries), nor is it possible or reasonable to run PHP or Java in the browser.

But nowadays it looks different. There are more Javascript libraries than PHP packages, the Javascript community is the fastest growing and much bigger than PHP. NodeJS engine is not only faster than PHP's engine, but also the standard runtime architecture (shared-nothing) of PHP is per se slow (although I tried to solve it with PHP-PM by killing shared-nothing). NodeJS itself is very stable and more than suitable for taking over the backend tasks. Here you can say with TypeScript that NodeJs competes with JVM rather than with PHP.

Since Javascript plain is not particularly pleasant to develop, it is indispensable to use TypeScript exclusively. Not only because you simply need the language features and security of the language to write robust code, but also because the good frameworks only make sense with TypeScript (and some of them are only available in TypeScript): This includes among others: Angular, TypeORM, NestJS, and many more. More about this in the technical comparison below.

This means that we already have a lot of business logic and code in TypeScript, for example when we use Angular or generally when we have some logic in the frontend. This logic no longer needs to be duplicated in the backend, as we can also write the backend with TypeScript, sharing utilities, models, validation, and more.

From an economic point of view, it no longer makes sense to have two technology stacks. The disadvantages of two such different technology stacks are obvious:

  • Unnecessarily great complexity.
  • Slower development because code cannot be shared.
  • Economically more expensive, because usually at least two developers of different groups are needed.
  • No knowledge transfer from backend <-> frontend.
  • Hiring is more difficult.

The technical comparison

To understand where TypeScript has its strengths over PHP, you need to place the technical features right next to each other.

Feature TypeScript PHP
Typed functions Yes Yes
Typed class properties Yes Soon
Typed variables Yes No
Complex types Yes No
Enums Yes Not native
Class initialized properties Yes No
Generics / Templates Yes No
Decorators Yes Hack via DocBlocks
Method overloading Yes Hack via magic methods
Native asynchronous code Yes No
Runs in Browser Yes No
Good for embedded devices Yes (LLVM) No
Compile time checks Yes No
Application server Default Hack via PHP-PM/ReactPHP
Interactive debugging Native XDebug (very slow)

With PHP 7 we got typed function signatures, i.e. we can define the data type of a function as well as its argument. A massive performance boost has also been added. PHP 7.4 will probably come 2019 with typed class properties, which means that class properties can now also define data types. Since PHP 7 other syntax sugar has been added, but these are rather small things I don't want to concentrate on now.

The whole strict type system, which is becoming more and more common in PHP, is essential to write solid code that doesn't break apart during refactoring. However, this type system is still very rudimentary, i.e. we can only define a few core data structures, e.g. string, boolean, float, integer, ClassName, object.

The important features, as can be seen in the table above, have by no means arrived in PHP, and probably never will. This is probably due to the fact that the core developers are personally pursuing other goals, but certainly also because the manpower to implement the features is lacking. Even the open source libraries are getting quieter and quieter. Not to mention the search for new talents or new maintainers for existing libraries.

Behind TypeScript and its base the NodeJS engine are the world's largest tech companies: Microsoft develops TypeScript, whereby Anders Hejlsberg (original author of Turbo Pascal) as core developer brings along his infinitely valuable wealth of experience. Google develops the JavaScript engine V8, which is the basis for NodeJS and Chrome. Millions, if not billions, of budgets are involved here. Unfortunately, a voluntarily led team can't keep up with that. Whether that's good or bad is on another page, in this blog post we discuss the technological results, not the ideological worldview of monopolizing technology.

Typed functions

PHP:

class Converter {
    public function convert(int $a): string {
       return '#' . $a;
    }
}

TypeScript:

class Converter {
    public convert(a: number): string {
       return '#' + a;
    }
}

Typed class properties

PHP (soon):

class Converter {
    public string $a;
}

TypeScript:

class Converter {
    public a: string;
}

Typed variables

TypeScript:

let a: string = 'Foo';

a = 3; //error

Complex types

Complex types like typed arrays, hash maps, or union types are not fully possible.

PHP:

/** @var string[] */
$a = [];
$a[] = 'Foo';


/** @var ??? */
$a = [];
$a['foo'] = new Converter()
$a['foo2'] = new Converter2();
$a['wrong'] = new WrongClass(); //valid

TypeScript:

let a: string[] = [];
a.push('Foo');

let a: {[name: string]: Converter | Converter2} = {};
a.foo = new Converter();
a.foo2 = new Converter2();
a.wrong = new WrongClass(); //error

Enums

Enums are in PHP basically nonexistent.  The language nor the engine nor the IDE can help you here. It's a complete mess during refactoring.

PHP:

abstract class PLAN
{
    const DEFAULT = 0;
    const PRO = 1;
    const ENTERPRISE = 2;
}

$plan = PLAN::DEFAULT;
$plan = 33; //valid

function doIt($plan): bool {
    return true;
}

doIt(PLAN::DEFAULT);
doIt(33); //valid

TypeScript:

enum PLAN {
    DEFAULT,
    PRO,
    ENTERPRISE
}

let plan = PLAN.DEFAULT;
plan = 33; //error

function doIt(plan: PLAN): boolean {
    return true;
}

doIt(PLAN.DEFAULT);
doIt(33); //error

Class initialized properties

In PHP you need a lot of boilerplate to set and initialise class properties from a constructor.

PHP:

class EmailTransport {
    private string $host;
    private string $username;
    private string $password;

    public __construct(string $host, string $username, string $password) {
        $this->host = $host;
        $this->username = $username;
        $this->password = $password;
    }
}

TypeScript:

class EmailTransport {
    public __construct(
        private host: string, private username: string, private password: string,
    ) {
    }
}

Generics / Templates

Generics aka templates is very powerful concept to make a certain function or class workable with different kind of data types.

PHP:

class Collection {
    /** @var array */
    private $items;

    public __construct($items) {
        $this->items = $items;
    }
    
    public add($item) {
        $this->items[] = $item;
    }
}

$collection = new Collection(['bla', 'blub']);
$collection->add(true); //valid

TypeScript:

class Collection<T> {
    constructor(private items: T[]) {

    public add(item: T) {
        this.items.push(item);
    }
}
let collection = new Collection<string>(['bla', 'blub']);
let collection->add(true); //error

Decorators

Although also in the professional environment heavily used in PHP, Decorators is not a language feature, but is specified via code comments blocks, which makes it very hacky and unstable across all code editors. In TypeScript Decorators is fully supported by the language itself.

Method overloading

Method overloading is supported in TypeScript and allows your IDE and compiler to give you very good guidance in case you make mistakes. In PHP overloading is possible via a workaround using magic methods __call, where only docBlocks can kindof "help" your IDE, but it is not a language feature, but rather from the community.

Native asynchronous code

Although in PHP we have ReactPHP, asynchronous code is not a language feature, and you feel exactly that when you start writing asynchronous code in PHP. It feels clunky and very unfinished. Syntax sugar like await in JavaScript is missing, which makes this functionality very rough to use. Also, when working with async functions, you might have a callback function. In PHP you probably would use anonymous functions, which behavior and look very ugly, since PHP has no concept of variables scopes like you know from JavaScript, and thus you need to declare all variables before using them via use ($foo) in the anonymous function.

Runs in Browser

Well, as we all know, JavaScript (and thus TypeScript) runs in every browser. TypeScript allows you to even support EcmaScript down to version 5.

Good for embedded devices

Thanks to the very fast v8 engine, you can either run TypeScript directly in V8 on a microprocessor, or you can use WebAssembly, that allows you to compile JavaScript directly to binary format (without JavaScript VMs).

Compile time checks

In TypeScript you always have a compile time, which means the tsc (TypeScript compiler) will compile your .ts files to .js files, or it is compiled in memory, like with ts-node. This includes very detailed checks so you don't have typos or use data types wrongly. In PHP you don't have a sophisticated type system nor does PHP compile your code before you deploy it to your application. Although, technically PHP compiles source code to opcode, this happens when the application starts, not beforehand, which makes it hard to track compile time issues.

Application server

One of the greatest strengths and at the same time weakness is PHP's shared-nothing architecture, which means every HTTP request has a new blank memory and all objects, variables, connections need to be created and established again and again. This makes PHP very slow, but on the other hand very easy to learn.

In PHP there are already a lot of people moving towards application servers like PHP-PM because of performance reasons. In TypeScript there's no such thing as shared-nothing architecture, so a http-application is automatically an application server.

Interactive debugging

In PHP we have XDebug, which is a voluntary made library. Although XDebug is well made and very valuable, it's also slow and lacks some features.
In NodeJS we have V8 engine and thus can use either WebStorms Debugging UI or Chrome developer tools. Both are wonderful and full features debuggers which do not make you application drastically slow.


Those were the technical points. Of course there are a lot of other points and features that differ from PHP, so I'd recommend you to check out the documentation of TypeScript: https://www.typescriptlang.org/docs/handbook/basic-types.html

Job market: employed and freelance

Job wise is super interesting to see more and more job opportunities coming up. As employed developer in Germany you can make 60.000 EURO and up a year easily, which is a very good salary. As freelance full-stack developer you make roughly 80 to 140 EUR/h, depending on experience and other skills, which means on average 150-200k EUR/year, which is an extremely good income and means you earn more than 99.9% of the people in the country. However, good people are rare and not all full-stack developers earn that much, because of region differences, personal skills, and other factors.

In my experience in PHP the freelance prices are lower, from 60-90 EUR/h, but this is still a very good income. It's mainly lower because as full-stack (which you are when you know NodeJs backend applications and Angular frontend) you need to know more and bring more value to the table, which leads to less people involved in the project overall and makes budget available.

The market has such good prices because it's not trivial to keep up with the technology and it's something fundamentally different to hack together some jQuery plugins on your website (like 5 years ago) and writing a full fledged web application in Angular 2+ using TypeScript with a NodeJS backend. Those web-developers with that old knowledge (jQuery and never worked with React/Angular) are not even demanded anymore and have a hard time finding a well-paid job.

In the future we probably see a more detailed split of backend vs frontend again in TypeScript, so companies will look for Backend TypeScript developers (with experience in databases, scaling, devops) and Frontend TypeScript developers (with experience in HTML engines, Angular/React, Cross device interfaces), which might change the salaries. However, I don't think the differences will be that big, as both groups can take advantage over each other and share knowledge, be it unit testing, CI integration, scaling, standard library functionality, and more. This is hardly possible with PHP/JavaScript or Java/JavaScript.

So keep in mind, if you go this route of being a TypeScript full-stack developer, it's more work to keep up than betting only on PHP. However the market pays outstandingly well and might be a path you want to follow.

Outlook

Of course I know the Nay-Sayers, who now say: "But PHP is still by far the most used language in the web environment, it won't change that fast, and besides I'm making enough money with it". That may be, but there are several factors why this is so. I can only counter this: Technology changes incredibly fast, the decay of PHP is noticeable. Without all the wild Wordpress installations, the number of PHP installations would be much lower. And PHP is very beginner-friendly because of its limited language and shared-nothing architecture. But these are exactly the ones that show the limits of PHP relatively quickly in the professional environment. TypeScript does not have these limits until much later and is nevertheless surprisingly beginner-friendly. And I mean, TypeScript is relatively new, the journey just bagan, and yet it has already outstanding libraries, like TypeORM and NestJS, which do not lack functionality compared to Symfony and Doctrine.

Of course NodeJS and TypeScript have its drawbacks as well and you might find some stuff that can be tweaked. The chances however are very high that your wishes will be addressed, as the community and financial backing is very huge. Typescript is currently developed incredibly fast and that will not change anytime soon. Also NodeJS and its V8 engine have massive support from big companies, which means the speed and robustness gets better and better.

And don't get me wrong: If you still have a good PHP job, have fun with it and earn well, then I congratulate you. But not everyone does, and there are many who are just starting out as developers for a few years or just starting out. Let me tell them: Don't just concentrate on one technology. The core skill of every good developer is to stay informed, test and learn new technologies and, if necessary, to include them in his knowledge base.