• Stars
    star
    955
  • Rank 47,869 (Top 1.0 %)
  • Language
    C#
  • License
    MIT License
  • Created over 10 years ago
  • Updated about 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Compile .NET assemblies to TypeScript and JavaScript

Netjs

Build Status

Netjs is a .NET to TypeScript and JavaScript compiler. It uses multiple stages to produce JavaScript for your web apps.

You start by compiling whatever code you want into its own assembly. Portable Class Libraries work great for this, but it really doesn't matter. You can even pass EXEs.

netjs Library.dll

This produces a TypeScript file. You can use this file as is if the rest of your app is written in TypeScript.

If you want JavaScript (with no dependencies), then pass this file along with a tiny mscorlib to the TypeScript compiler:

tsc -t ES5 mscorlib.ts Library.ts --out Library.js

You can now include Library.js in any app because it is fully linked (you will get build errors if anything is missing).

<script src="Library.js" type="text/javascript"></script>

And that's it. You can write apps and reuse the portable parts in web apps!

Installation

dotnet tool install -g netjs

Install TypeScript

The TypeScript compiler is needed to convert from TypeScript files to JavaScript.

First, install Node.

sudo npm install -g typescript

Compiling Code

Netjs works with .NET assemblies built with any compiler ([limitations][Limitations] not withstanding).

Compile to TypeScript

netjs Library.dll

This will output a TypeScript file named Library.ts containing all the code from Library.dll and any other assemblies referenced in its directory.

Compile to JavaScript

tsc -t ES5 mscorlib.ts Library.ts --out Library.js

This compiles the library code along with a small implementation of mscorlib. The files are merged and output as a single JavaScript file Library.js.

ECMAScript 3 Compatibility

In case you need your code to run in es3 environment (like, well, IE8), you have to get rid of accessors as they are not supported. Passing --es3 as an argument would result in creating of getter/setter methods instead of fields with accessors.

netjs Library.dll --es3

Library.dll:

class Person
{
    private string name;
    public string Name
    {
        get { return name; }
        set { name = value; }
    }
}

Library.ts:

class Person extends NObject
{
    name: string;
    SetName(value: string): void
    {
        this.name = value;
    }
    GetName(): string
    {
        return this.name;
    }
}

And then compile TypeScript for ES3. Also use es3 compatible mscorlib.

tsc -t ES3 mscorlib.es3.ts Library.ts --out Library.js

Since all the references and assignments of all fields with accessors, including native ones, are replaced with methods invocations, you have to provide a corresponding implementation. In mscorlib.es3.ts all accessors are replaced with getter/setter methods.

Philosophy

[History][] is filled with other IL to JS compilers, why Netjs?

Because I am not happy with the JavaScript generated by current solutions.

The best solutions currently generate a lot of code in an attempt to maintain all the finer points of .NET semantics. The philosophy of Netjs is that .NET and JavaScript's semanantics are close enough that idiomatic JavaScript can be generated from any .NET library. Sure we have to work around some of .NET's features, but the majority of code should be clean JavaScript.

Well, that's almost true - JavaScript's idioms don't exactly match .NET's. However, TypeScript's come a lot closer. For this reason, Netjs leverages the TypeScript compiler. This also performs a great "first unit test" on the generated code because the TypeScript compiler is very strict and is good at catching errors.

When I declare a class with properties in C#,

class Person {
    public DateTime DateOfBirth { get; set; }
    public int Age {
        get {
            var now = DateTime.Now;
            return (new DateTime (dob.Year,now.Month,now.Day) >= dob) ? 
                now.Year - dob.Year : 
                now.Year - dob.Year - 1;
        }
    }
}

The code generated should be idiomatic JavaScript. And it is:

var Person = (function (_super) {
    __extends(Person, _super);
    function Person() {
        _super.call(this);
        this.DateOfBirth = null;
    }
    Object.defineProperty(Person.prototype, "Age", {
        get: function () {
            var now = DateTime.Now;
            var flag = DateTime.op_GreaterThanOrEqual(new DateTime(this.DateOfBirth.Year, now.Month, now.Day), this.DateOfBirth);
            return (!flag) ? (now.Year - this.DateOfBirth.Year - 1) : (now.Year - this.DateOfBirth.Year);
        },
        enumerable: true,
        configurable: true
    });
    return Person;
})(NObject);

There's a tiny wrapper placed around the class definition that is typical of JavaScript code avoiding name conflicts. There is the use of a tiny __extends function that establishes a class hierarchy using JavaScript's prototype chain. The rest is standard JavaScript.

I want to make life easier for the machine by generating clean idiomatic code, but I also want it to be easier for us developers.

When it comes time to use the Person class from JavaScript, that code should also be clean and idiomatic:

<script>
    var p = new Person();
    p.DateOfBirth = new DateTime(1980, 7, 23);
    document.getElementById("age").textContent = p.Age;
</script>

History

Netjs is not the first project that compiles .NET IL to JavaScript. It is, in fact, my second attempt at such an app. The first worked, but wasn't good enough for release.

Microsoft built their own named Project V. It was glorious, as was the amount of JavaScript it created. "Hello world" generated gigabytes of JavaScript. Serisously, I once calculated that the heat death of the universe would occur before it had finished outputting a foreach loop. You see, the JavaScript it output rigorously obeyed .NET semantics - it was as if a virtual machine vomitted all over your code. Glorious. Anyway, Microsoft cancelled the project.

Then the world was blessed with JSIL. This is Project V done right. It's still a virtual machine vomitting all over your code, but it's a clean nice kind of vomit that is measured in megabytes instead of gigabytes. It's powerful enough to compile the BCL and MonoGame - a truly powerful compiler. It's going to generate a lot code and you're might end up with a loading screen, but it does its job well.

Limitations

  • Namespaces are ignored
  • mscorlib.ts is a tiny subset of the full BCL
  • Overloaded methods generally work, but have trouble with:
    • One overload being virtual and another not (it hurts my head trying to get this to work)
    • Overloads that have the same argument count and accept values that can be null (runtime type checking is used)
    • Overloaded constuctors that call different base constructors probably don't work
  • Async does not work
  • Gotos only sometimes work
  • Regexes have some problems:
    • Named groups don't work (we rely on the browser's regex implementation)
    • Match Group Index only works if you capture everything
  • Integer casts with the expectation of performing a Truncate operation don't work ()
  • Seriously, watch it with those overloads

If any of these bother you, then please go use JSIL.

Thank you!

Netjs owes the majority of its intelligence to Mono.Cecil, NRefactory, and ILSpy's decompiler. Without these projects, Netjs would not exist. Thank you!

License

The MIT License (MIT)

Please see LICENSE.txt for details.

More Repositories

1

sqlite-net

Simple, powerful, cross-platform SQLite client and ORM for .NET
C#
3,753
star
2

Ooui

A small cross-platform UI library that brings the simplicity of native UI development to the web
C#
1,616
star
3

NGraphics

NGraphics is a cross platform library for rendering vector graphics on .NET. It provides a unified API for both immediate and retained mode graphics using high quality native renderers.
C#
696
star
4

FuGetGallery

An alternative web UI for browsing nuget packages
C#
672
star
5

webgpu-torch

Tensor computation with WebGPU acceleration
TypeScript
488
star
6

Continuous

Continuous IDE Addin enables live coding from Xamarin Studio and Visual Studio
C#
268
star
7

CLanguage

C parser, compiler, and interpreter for .NET
C#
252
star
8

Bind

A small but powerful C# library for data binding
C#
205
star
9

CrossGraphics

Cross-platform Graphics Library for .NET
C#
194
star
10

transformers-js

Browser-compatible JS library for running language models
JavaScript
178
star
11

ImmutableUI

Immutable objects that mirror popular object oriented UIs
C#
115
star
12

ListDiff

C#
113
star
13

Iril

Compiles LLVM IR (bytecode) or C to .NET Assemblies
LLVM
94
star
14

web-transformers

Transformer neural networks in the browser
TypeScript
89
star
15

Praeclarum.MacCatalyst

Convert your Xamarin.iOS apps to Mac Catalyst apps by adding this nuget.
C#
63
star
16

Csg

Solid modeling library for .NET
C#
62
star
17

AskGPT

Ask ChatGPT questions from the command line.
C#
58
star
18

SwiftSharp

Swift compiler for .NET
HTML
52
star
19

Gone

GO compiler for .NET
F#
42
star
20

HotDogOrNot

A minimal Xamarin CoreML app to detect hotdogs
C#
40
star
21

lcars

LCARS Reader - the coolest iPad news reader not on the App Store
C#
36
star
22

CSharpInteractive

C# Interactive is a REPL for C# in Xamarin Studio
C#
30
star
23

Praeclarum

My general purpose library
C#
29
star
24

QuickTest

C#
28
star
25

GooglePlus

GooglePlus API Documentation and .NET Implementation
C#
27
star
26

MetalTensors

.NET Neural Network training library using Apple's Metal Performance Shaders
C#
26
star
27

runcs

The C# compiler hosted in a web app
C#
26
star
28

odata

OData Browser for the iPhone
C#
26
star
29

CSharpToSwift

Converts your C# projects to Swift
C#
23
star
30

StopCrashing

Script to detect possible sources of crashes in Xamarin apps
F#
21
star
31

FunctionalMeetup

Example code for Frank Krueger's Functional Mobile Apps talk at NDC Oslo 2016
F#
19
star
32

EasyLayout

EasyLayout makes writing auto layout code in Xamarin.iOS easier.
C#
18
star
33

SdfKit

.NET library to convert signed distance functions (SDFs) into triangle meshes and 3D renders
C#
17
star
34

OouiChat

Chat room web app built using Xamarin.Forms, ASP.NET, and Ooui
C#
16
star
35

MarriageClock

An IoT thing in the shape of heart that tells you how long you've been married
C++
13
star
36

ThreeDO

C#
13
star
37

Ur

Game of Ur using Blazor
C#
13
star
38

CircuitTranslations

Language support for iCircuit
F#
13
star
39

ARDemo

Xamarin Evolve 2014 Augmented Reality Demo
C#
12
star
40

fuget

C#
10
star
41

praeclarum.github.io

Frank A. Krueger's blog
HTML
10
star
42

caulker

3D Map for MonoTouch
C#
10
star
43

WebGlobe

3D Globe Screensaver Written in WebGPU
JavaScript
9
star
44

JavaScriptLanguage

Resharper add-in that decompiles to JavaScript.
C#
8
star
45

NMusic

Library and demo app for composing music and playing it on iOS
C#
8
star
46

Demo11

iOS 11 Demo Code Presented at the Seattle Mobile .NET Meetup
C#
8
star
47

BuildLight

Show IDE build status using an IoT device
C#
8
star
48

circuitpython-net

CircuitPython compiled to run on .NET
C#
8
star
49

CuneiformTranslators

Neural network trained to translate from ancient languages to modern languages
Jupyter Notebook
8
star
50

ukf

Unscented Kalman Filter Library
7
star
51

ClrTools

Tools for .NET Developers
C#
7
star
52

ImageRecognizer

Uses Metal Performance Shaders on iOS 13+ to train a neural network to recognize shapes
C#
7
star
53

rt

My Pet Raytracer in C#
C#
6
star
54

Monospace11

Demo code from Frank Krueger's talk at Monospace
C#
6
star
55

rouse

Declarative RESTful server
C#
5
star
56

NEcho

Amazon Echo ("Alexa") ASP.NET Core Web Service
C#
5
star
57

html5

C#
5
star
58

NeuralScanner

C++
4
star
59

Fom

F#
4
star
60

VectorPerf

Measures the performance of different vector types in .NET
C#
4
star
61

Knossus

Quick and easy web apps
C#
4
star
62

WasmAloneLab

HTML
4
star
63

UIDays

Cataloging the release dates of various UI frameworks
4
star
64

HomeAI

C#
4
star
65

ColmapSharp

COLMAP builds and bindings for .NET
C++
4
star
66

SubMark1Sim

F# Code to visualize a submarine control simulation
F#
3
star
67

AppleNative.Templates

F#
3
star
68

dotnet-tree-sitter

.NET bindings to the Tree-sitter parsing library
Makefile
3
star
69

Lilui

The lilest cross platform UI library for .NET
C#
3
star
70

BuildBoard

Display build status on an LED matrix
C++
2
star
71

nerf-py

Python
1
star
72

VacuumMold

C#
1
star
73

PythonRepl

Python REPL for iOS using Xamarin and IronPython
C#
1
star
74

BoxEditor

Generic box-based diagram editor for .NET
C#
1
star
75

Armina

Programming language cross compilation tools
C#
1
star