N4JS Language & IDE

N4JS Language and IDE Features

The following table gives an overview of features implemented by N4JS.


  • The parser fully supports ECMAScript 2015 syntax including unicode escape sequences, regular expressions and automatic semicolon insertion. Not all constructs are fully supported by the type-checker yet.

  • The transpiler translates N4JS to V8-compatible JavaScript. ES2015 constructs not supported by latest V8 are rejected by N4JS.

  • Except project (as an access modifier, will be removed in future versions as it is the default), N4JS does not introduce any new keywords to ECMAScript 2015/ES.next. If additional functionality requires explicit declarations, this is done via annotations similar to Java (using @). There are no user-defined annotations supported at the moment (this is why we do not list annotations as a feature).

Feature Table

Statements and expressions


Similar to


ECMAScript 5


ES5 expressions, statements and declarations are fully supported (except scoping in with-statement) including type constraints and inference.

Import, Export


import statement fully supported, exporting declarations is supported, re-export not fully supported yet, no relative imports, no anonymous default export.

Scoping and access restrictions

for..of loops


Fully supported including destructuring.

Function scoping


ES5-like function scoping with var

Block scoping


ES2015-like block scoping with let and const



const variables (requiring initializers at declaration) with block scoping using keyword const

Final fields


final fields (requiring initialization in constructor) with annotation @Final

Access modifiers


Access modifiers almost similar to Java: public, protected, private. Instead of package, project is introduced limiting access to the current project or component. For larger projects with components from multiple vendors, an additional modifier @Internal is introduced to restrict access to vendor-types only.

String templates


ES2015-like string templates with validation (of expressions inside the template).


Function objects


Function (and method) expressions and declarations are modeled as function objects (with function type)

Function subtyping


Override compatibility (similar to Java) with notion of ECMAScript semantics (superfluous or variadic parameters)

Arrow expression


Arrow functions with this binding according to ES2015

Rest parameters


Fully supported, parameters are treated as arrays inside function

Optional parameters

Parameters can be marked optional. This is going to be replaced with ES2015 default parameters.

Super calls


Inside methods (of classes), super can be used to call overridden method (or constructor)



Syntax supported but not supported by language (type checker) yet.

Declared types



Class declarations as in ES2015 (or Java) with single inheritance but implementation of multiple interfaces as in Java)



Interface declarations with default methods (as in Java 8) and data fields (treated as default implementation, can be implemented with field accessors). instanceof operator can be used with interfaces as well.


˜ TS

Simple enumerations with literals and basic reflection

String-based enums

string based enumerations, literals are of type string



Methods as in ES2015, including constructor and static methods; overridden or implemented members are to be annotated with @Override as in Java

Field accessors


Getters and setters (in object literals and classes, instance and static); at the moment pairs are automatically recognized, will be changed to ES2015 semantics

Data fields


Instance and static fields including initializers as in Java

Class modifiers


As in Java, classes can be declared abstract or final (using @Final annotation).


Type annotation


Type annotations using colon syntax similar to ECMAScript 4 proposal or TS, some special types use different syntax (will probably be adjusted to be compatible with TS)



Top type (super type of every other type), used as default type in N4JS files if no more specific type is declared or can be inferred. No property access is possible, since any has no properties. This is probably the most important difference to TypeScript: In TypeScript anything can be called on any, in N4JS nothing! However, this can be changed with a dynamic modifier, see below.



primitive types as in ES5 (number, string, boolean), special types null and undefined (with special variant void to be used for return type)


primitive type int, at the moment used synonymously to number, will be stricter checked and handled in future releases



minimal support for symbols, basically only predefined symbols, more support may be added

Nominal types


By default, all subtyping is done nominally as in Java, i.e. subtype relations are to be explicitly declared with extends and implements

Structural types

˜ TS

Modifiers at declarations or references enable structural subtyping. Access modifiers are taken in to account, i.e. only public members become part of a structural type.

Field structural type

Similar to structural typing, but only fields (data/accessors) are taken into account. Different variants (all fields, read-only fields/getter, write-only fields/setter, initializer variant for special constructor initializer) supported.

Static types


By default, only declared properties of a type can be accessed. This is true independent from the syntax (property access with dot-syntax (a.x) or index access (a["x"]). To model the map-behavior of Object, arbitrary index access on variables of type Object is allowed.

Dynamic types

Type modifier + enables arbitrary property access. Actually any+ is similar to TypeScript’s any semantics. This is known to be unsafe, so it is not the default behavior (in particular not for any) but only to be used as an "escape hatch".



Arrays are modeled as a generic type (extending Object)

Object literals


Object literals are modeled as structural types (\~Object with { properties })

Type cast

˜ TS

Expressions can be explicitly casted to a type via as


Generic types


Generic class and interface declarations, parameterized type references (raw type usage not allowed)

Generic functions and methods


Generic functions (and methods)

Type variables, wildcards


Type variables (in declarations) and wildcards (in references) with upper and lower bounds</tr>

Type variable inference


Type variables are inferred if not explicitly bound by type arguments in the reference, this is particularly important for generic function/method calls. The type inference algorithm matches the Java 8 specification.

Type Constructors and Special Types

Union type

˜ TS

An union type defines that a variable (of that type) is subtype of (at least) one type defined in the union. Without further type checks, only members available in all types of the union are available. In case of methods, formal parameter types are merged by means of intersection types (and return types by means of union types)

Intersection type


An intersection type defines that a variable (of that type) is subtype of all types defined in the intersection. Thus, members defined in any type of the union are available. Property access to intersection types is not fully supported yet.

Constructor type

˜ TS

Type of a (non-abstract) class declaration or expression itself. Special subtyping rules are implemented, i.e. constructor signature is taking into account.

type type

Type of a class or interface declaration, without any constructor. That is, variables of this type cannot be used in new-expressions. However, this type is useful in combination with static polymorphism.</tr>

this type

˜ TS

Type of the this-literal, can be used in combination with structural typing. Via annotation @This this type can be explicitly defined for functions.

Dynamic polyfills

In order to model the commonly used pattern of polyfills and to add new properties to built-in types (as in ES2015), dynamic polyfills can be defined (in definition modules only). They look like partial classes. The modules defining these polyfills may define (plain JS) modules which are to be executed at initialization time in order to apply the polyfills at runtime.

Static polyfills

In larger projects, often classes are automatically generated. In order to enrich these classes without changing the generator, static polyfills can be defined. The transpiler merges these static polyfills into the original modules.

Asynchronous Programming



Object type Promise as defined in ECMAScript 2015 defined as ES2015 API type



async and await keywords for implicit promises, syntax and semantics closely follow ES proposal; transpiled to generator functions; validation checks correct usage of async await, async functions will implicitly return Promises. async can be used with function or method declarations, function and arrow expressions


Via annotations @Promisifiable ES5-conform functions following code conventions for asynchronous callback parameters (last parameter is a callback function etc.) can be used as if they were defined with async keyword, i.e. they can be used with await keyword (or a promise can be retrieved via annotation @Promisify)

Components and Modules


N4JS and the N4JS IDE use the notion of components (or projects). An N4JS component is described with a manifest, in which the component and its dependencies are defined. N4JS introduces different component types: Runtime libraries and runtime environments define capabilities of specific JavaScript engines and execution environments (such as node.js vs. browser); test components have extended access to the tested components



N4JS defines modules similar to ES2015, these modules are transpiled to V8-compatible JavaScript

Type definition modules


In order to provide type annotations for existing projects, definition files (n4jsd) are used.

Module Loader


Unified output with support for System.js and Common.js (Node.js implementation) module loaders. Since System.js enables better handling of dependency cycles, this is the default loader used by the IDE

Dependency Injection


Dependency injection is supported using annotations similar to JSR-330 (probably better known from Guice) and more to reduce client side glue code. Fields (and parameters) can be injected via @Inject, injectors can be easily set up via @GenerateInjector and configured with binders (and @Bind annotation). The built-in framework supports nesting of injectors, different injection points (field, constructor, method), providers and different scopes (default, singleton, injection-chain-singleton).


ES5 object types


All ECMAScript 5 object types are available in N4JS, type annotations are built-in

ES2015 object types


ECMAScript 2015 object types are defined by means of runtime libraries and a runtime environment. N4JS does not provide any implementation of these object types. Also, not all details are defined yet. This will be updated in future releases, depending also on V8 capabilities. However, the most important object types such as collections are defined already.


Besides ECMAScript reflection mechanisms, N4JS provides additional reflection at runtime via a built-in class N4Class. This class provides basic information at the moment, this will be improved in future releases


JUnit-like annotations


Tests can be annotated similar to JUnit, i.e. tests methods with @Test, setup code with @Before/@BeforeAll etc.

Built-in Test Framework

An xUnit-like test framework "mangelhaft" using test annotations is provided with the IDE

Extended Access

Test classes (in special test components) have extended access to tested projects, e.g., can access non-public members

Test Execution

Tests can be started from the IDE using node.js. It is possible to run single test modules, single methods, or whole packages/projets.

node.js Support

Dynamic Import

In order to use projects without type annotations, the dynamic module import can be used to make the module dynamic (so that arbitrary properties can be accessed)

Automatic download of Type Definitions

If available, type definitions are automatically downloaded when an NPM module is installed via the IDE. New type definitions will be added in the future.


Modules can be run from the IDE using node.js, either using module loader System.js (default) or Common.js

npm Export

Components an be exported to the file system, package.json is automatically created and content is organized according to NPM convention — ready to be published with NPM (which is not done automatically in order to avoid rash publications)

N4JS IDE Features

Syntax highlighting

Syntax highlighting with special highlighting of type annotations, can be used for editing n4js, n4jsd or plain js files

Immediate validation

Code is validated as you type

Incremental builder

Code is transpiled as you save, only effected modules will be re-compiled

Content assist

Basic content assist (propose properties of the receiver, keywords) is working; will be improved in future releases


Quick fixes to solve common issues, e.g. adding missing annotations or modifiers; more quickfixes will be added in future releases


Wizards for creating new projects, classes or interfaces. More wizards will be added in future releases

Organize imports

Automatically add missing imports and remove unused imports. A lso content assist and quickfixes will add imports - you never have to type import statements.

Project and outline view

Project view showing all components in workspace, (quick) outline view to easily navigate to declared elements.

Jump to declaration

Navigate from reference to bound declaration

Find all references

Find all references bound to a declaration

Error reporting

We embrace bug reports! In order to enable easier writing of bug reports, language tests can be written inside the IDE. This feature will be improved in the future.


Since the IDE is based on Eclipse, additional features such as git support are integrated or can easily be installed

N4JS Headless Compiler


The headless compiler is workspace aware, i.e. it can compile all projects with a single command. This makes it very easy to set up CI jobs. At the moment, the headless compiler is made available as a jar-file. Additional support simplifying installation and usage will be added in future releases




available, although there might be bugs in the alpha-release.


mostly available, some aspects or parts of the feature are not implemented yet or will be improved in the future.


feature available but syntax or semantics will be changed in future releases


planned for future releases but not implemented yet.




ECMAScript Language Specification / ISO/IEC. Geneva, Switzerland, Juni 2011 (ECMA-262, 5.1 Edition)


ECMAScript 2015 Language Specification / ISO/IEC (ECMA-262, 6th Edition). โ€“ International Standard.


Proposed ECMAScript 4th Edition โ€“ Language Overview / ECMA. โ€“ Proposal, PDF.


ECMAScript proposals (ECMAScript 2017 or later or never)


Hejlsberg, Anders ; Lucco, Steve: TypeScript Language Specification. 1.8. Microsoft, Januar 2016. ˜ TS means almost similar functionality, !TS refers to similar concepts but with major differences.


Gosling, James et al: The Java Language Specification. Java SE 8 Edition. JSR-337 Java SE 8 Release Contents.