JavaScript also runs outside of the browser nowadays, so what.
Likewise UNIX made C unavoidable in systems programming for timesharing servers, eventually like JavaScript outgrew the browser, certain people wanted to run C in their microcomputers.
As for why C has staying power, that's solely a function of its early success. There's nothing about the language itself that isn't better provided for by some of its historic competitors (e.g. Modula-2). But there's a self-reinforcing loop here, where all new hardware platforms start with C as a basis because it lets you write all the existing code; and conversely, using C is the way to ensure that your code will work even on future platforms.
B was also written as a hack - it was basically a minimal subset of BCPL small enough to fit in the memory of the machines they were working with. B is elegant in a sense that it's a very simple language for a word-oriented architecture - but that's exactly the part that they had to get rid of for C to target byte-oriented ones. Coincidentally, it's also one of the sources of weirdness in C syntax (e.g. implicit int and K&R prototypes are all legacy of B).
For me this is beautiful:
https://briancallahan.net/blog/20220220.html
I'm sure it's just a hack to you, but you can't do that in Pascal.
I mostly like C because of what I wrote here: https://news.ycombinator.com/item?id=30404529
The only thing your blog post demonstrates is that C has a built-in textual macro facility. But if you wanted the same in Pascal, you could have it just the same, by running it through the C preprocessor; or better yet, something more powerful like M4. Of course, you'd have to deal with various impedance mismatches, such as the fact that the definition of "token" is different between the preprocessor and the compiler - but that's also true of C! In fact, this discrepancy alone is quite sufficient to deem C inelegant, in my opinion.
Taking a contrarian view to everyone else in this thread, I don't think Unix rocketed C to stardom - Turbo C did. Turbo Pascal was very very popular for PC programming and was eventually supplanted by Turbo C and Turbo C++. Without Turbo C, I think C would have probably become just another niche language used on a niche OS, Unix.
And in line with what you say in another comment, commercial OSes -- including VMS -- were very powerful and much more popular than Unix. In 1982, a single VAX 11/780 running VMS with 4 and 8 MB of RAM could support 10s of programmers editing, compiling, debugging, and testing code. VMS was also a real-time operating system that we used in production to control/monitor/perform-I/O hardware devices handling LANDSAT image data. And Unix is still trying to figure out async I/O ... (Most of my career has been spent on Unix, but I appreciate other operating systems I've worked on as well.)
Lisp has the code-data duality (everything is a list) going for it and C has everything is pointer to a block of memory and that's it. That block can be a device register, data structure, array of sth. or just about anything you can imagine. This idea enables you some kind of proto-polymorphism without the verbosity and chains of higher level languages (at the cost of safety of course). That is the beauty of C and unlike Lisp it is also lot closer to the metal, which helped a lot with performance.
I think it's normal to be jaded when something objectively superior is being replaced with something simpler. But that doesn't mean the simpler thing is without merit. The world has more dimensions, the technical aspect is just one of it.
C is not significantly different from Algol or Pascal. The difference between C and Algol is a lot smaller than between either of those and Lisp or ML.
What's missing in some Algol-like languages compared to C is the loose pointer arithmetic, and possibly type punning via pointer conversions. Those features allow C programmers to do things like write their own memory allocator, which is incredibly useful in embedded systems. A C project can produce a self-contained image that boots on bare metal, with minimum assembly language. Or on almost bare metal, where there is a boot loader program that provides no services to the C program other than jumping to its entry point and maybe some console printing routines or something.
As an embedded developer in previous life, I can assure you C is not special because it can run on bare metal. Many other languages can too.