Introduced const implementation.
diff --git a/src/njs_builtin.c b/src/njs_builtin.c
index abb6cee..5b03e72 100644
--- a/src/njs_builtin.c
+++ b/src/njs_builtin.c
@@ -972,7 +972,7 @@
 
     var = node->variable;
 
-    if (var->type == NJS_VARIABLE_LET) {
+    if (var->type == NJS_VARIABLE_LET || var->type == NJS_VARIABLE_CONST) {
         return NJS_DECLINED;
     }
 
diff --git a/src/njs_disassembler.c b/src/njs_disassembler.c
index 3a19387..acfc5e2 100644
--- a/src/njs_disassembler.c
+++ b/src/njs_disassembler.c
@@ -150,6 +150,9 @@
 
     { NJS_VMCODE_NOT_INITIALIZED, sizeof(njs_vmcode_variable_t),
           njs_str("NOT INIT        ") },
+
+    { NJS_VMCODE_ASSIGNMENT_ERROR, sizeof(njs_vmcode_variable_t),
+          njs_str("ASSIGNMENT ERROR") },
 };
 
 
diff --git a/src/njs_generator.c b/src/njs_generator.c
index 55f274f..56cb6fe 100644
--- a/src/njs_generator.c
+++ b/src/njs_generator.c
@@ -287,6 +287,7 @@
 
     case NJS_TOKEN_VAR:
     case NJS_TOKEN_LET:
+    case NJS_TOKEN_CONST:
         return njs_generate_var_statement(vm, generator, node);
 
     case NJS_TOKEN_IF:
@@ -640,7 +641,7 @@
         return NJS_OK;
     }
 
-    if (var->type == NJS_VARIABLE_LET) {
+    if (var->type == NJS_VARIABLE_LET || var->type == NJS_VARIABLE_CONST) {
         scope = njs_function_scope(node->scope);
 
         if (scope->dest_disable) {
@@ -692,7 +693,7 @@
         return NJS_OK;
     }
 
-    if (var->type == NJS_VARIABLE_LET) {
+    if (var->type == NJS_VARIABLE_LET || var->type == NJS_VARIABLE_CONST) {
         scope = njs_function_scope(node->scope);
 
         if ((!scope->dest_disable && njs_function_scope(var->scope) == scope)) {
@@ -746,6 +747,12 @@
 
     if (expr == NULL) {
         /* Variable is only declared. */
+
+        if (var->type == NJS_VARIABLE_CONST) {
+            njs_syntax_error(vm, "missing initializer in const declaration");
+            return NJS_ERROR;
+        }
+
         if (var->type == NJS_VARIABLE_LET) {
             ret = njs_generate_let(vm, generator, node, var);
             if (njs_slow_path(ret != NJS_OK)) {
@@ -758,7 +765,7 @@
         return NJS_OK;
     }
 
-    if (var->type == NJS_VARIABLE_LET) {
+    if (var->type == NJS_VARIABLE_LET || var->type == NJS_VARIABLE_CONST) {
         ret = njs_generate_wo_dest(vm, generator, expr);
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
@@ -1346,7 +1353,9 @@
 
     let = node->right;
 
-    if (let->token_type != NJS_TOKEN_LET) {
+    if (let->token_type != NJS_TOKEN_LET
+        && let->token_type != NJS_TOKEN_CONST)
+    {
         return NJS_OK;
     }
 
@@ -1827,7 +1836,9 @@
             goto statement;
         }
 
-        if (!var->init && var->type == NJS_VARIABLE_LET) {
+        if (!var->init && (var->type == NJS_VARIABLE_LET
+            || var->type == NJS_VARIABLE_CONST))
+        {
             njs_generate_code(generator, njs_vmcode_variable_t, code,
                               NJS_VMCODE_INITIALIZATION_TEST, 0, right);
             code->dst = right->index;
@@ -1950,8 +1961,10 @@
 {
     njs_int_t              ret;
     njs_index_t            index, src;
+    njs_variable_t         *var;
     njs_parser_node_t      *lvalue, *expr, *object, *property;
     njs_vmcode_move_t      *move;
+    njs_vmcode_variable_t  *var_code;
     njs_vmcode_prop_set_t  *prop_set;
 
     lvalue = node->left;
@@ -1961,11 +1974,19 @@
     if (lvalue->token_type == NJS_TOKEN_NAME) {
 
         ret = njs_generate_variable(vm, generator, lvalue, NJS_DECLARATION,
-                                    NULL);
+                                    &var);
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
         }
 
+        if (var != NULL && var->type == NJS_VARIABLE_CONST) {
+            njs_generate_code(generator, njs_vmcode_variable_t, var_code,
+                              NJS_VMCODE_ASSIGNMENT_ERROR, 0, node);
+            var_code->dst = var->index;
+
+            return NJS_OK;
+        }
+
         expr->dest = lvalue;
 
         ret = njs_generator(vm, generator, expr);
@@ -2075,9 +2096,11 @@
 {
     njs_int_t              ret;
     njs_index_t            index, src;
+    njs_variable_t         *var;
     njs_parser_node_t      *lvalue, *expr, *object, *property;
     njs_vmcode_move_t      *move;
     njs_vmcode_3addr_t     *code;
+    njs_vmcode_variable_t  *var_code;
     njs_vmcode_prop_get_t  *prop_get;
     njs_vmcode_prop_set_t  *prop_set;
 
@@ -2086,11 +2109,19 @@
     if (lvalue->token_type == NJS_TOKEN_NAME) {
 
         ret = njs_generate_variable(vm, generator, lvalue, NJS_DECLARATION,
-                                    NULL);
+                                    &var);
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
         }
 
+        if (var != NULL && var->type == NJS_VARIABLE_CONST) {
+            njs_generate_code(generator, njs_vmcode_variable_t, var_code,
+                              NJS_VMCODE_ASSIGNMENT_ERROR, 0, node);
+            var_code->dst = var->index;
+
+            return NJS_OK;
+        }
+
         index = lvalue->index;
         expr = node->right;
 
@@ -2616,8 +2647,10 @@
 {
     njs_int_t              ret;
     njs_index_t            index, dest_index;
+    njs_variable_t         *var;
     njs_parser_node_t      *lvalue;
     njs_vmcode_3addr_t     *code;
+    njs_vmcode_variable_t  *var_code;
     njs_vmcode_prop_get_t  *prop_get;
     njs_vmcode_prop_set_t  *prop_set;
 
@@ -2626,11 +2659,19 @@
     if (lvalue->token_type == NJS_TOKEN_NAME) {
 
         ret = njs_generate_variable(vm, generator, lvalue, NJS_DECLARATION,
-                                    NULL);
+                                    &var);
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
         }
 
+        if (var != NULL && var->type == NJS_VARIABLE_CONST) {
+            njs_generate_code(generator, njs_vmcode_variable_t, var_code,
+                              NJS_VMCODE_ASSIGNMENT_ERROR, 0, node);
+            var_code->dst = var->index;
+
+            return NJS_OK;
+        }
+
         index = njs_generate_dest_index(vm, generator, node);
         if (njs_slow_path(index == NJS_INDEX_ERROR)) {
             return index;
diff --git a/src/njs_parser.c b/src/njs_parser.c
index 616b832..aae187d 100644
--- a/src/njs_parser.c
+++ b/src/njs_parser.c
@@ -4946,6 +4946,7 @@
 njs_parser_expression_statement(njs_parser_t *parser, njs_lexer_token_t *token,
     njs_queue_link_t *current)
 {
+    njs_token_type_t   type;
     njs_lexer_token_t  *next;
 
     switch (token->type) {
@@ -4974,15 +4975,20 @@
 
         break;
 
+    case NJS_TOKEN_CONST:
     case NJS_TOKEN_LET:
+        type = token->type;
+
         token = njs_lexer_peek_token(parser->lexer, token, 0);
         if (token == NULL) {
             return NJS_ERROR;
         }
 
         if (token->type == NJS_TOKEN_NAME) {
-            njs_parser_syntax_error(parser, "let declaration cannot appear "
-                                            "in a single-statement context");
+            njs_parser_syntax_error(parser, "%s declaration cannot appear "
+                                    "in a single-statement context",
+                                    (type == NJS_TOKEN_CONST ? "const"
+                                                             : "let" ));
             return NJS_DONE;
         }
 
@@ -5307,6 +5313,7 @@
 
     case NJS_TOKEN_VAR:
     case NJS_TOKEN_LET:
+    case NJS_TOKEN_CONST:
         token_type = token->type;
 
         token = njs_lexer_peek_token(parser->lexer, token, 0);
@@ -5328,9 +5335,6 @@
 
         break;
 
-    case NJS_TOKEN_CONST:
-        return njs_parser_not_supported(parser, token);
-
     default:
         njs_parser_next(parser, njs_parser_expression);
         break;
@@ -5368,6 +5372,10 @@
         type = NJS_VARIABLE_LET;
         break;
 
+    case NJS_TOKEN_CONST:
+        type = NJS_VARIABLE_CONST;
+        break;
+
     default:
         type = NJS_VARIABLE_VAR;
         break;
diff --git a/src/njs_scope.h b/src/njs_scope.h
index 6771e58..94e58be 100644
--- a/src/njs_scope.h
+++ b/src/njs_scope.h
@@ -82,7 +82,7 @@
     value = njs_scope_value(vm, index);
 
     if (!njs_is_valid(value)) {
-        if (njs_scope_index_var(index) == NJS_VARIABLE_LET) {
+        if (njs_scope_index_var(index) <= NJS_VARIABLE_LET) {
             njs_reference_error(vm, "cannot access to variable "
                                     "before initialization");
             return NULL;
diff --git a/src/njs_variable.c b/src/njs_variable.c
index 5a532fb..f775aef 100644
--- a/src/njs_variable.c
+++ b/src/njs_variable.c
@@ -184,6 +184,7 @@
     }
 
     switch (type) {
+    case NJS_VARIABLE_CONST:
     case NJS_VARIABLE_LET:
         if (scope->type == NJS_SCOPE_GLOBAL
             && parser->undefined_id == unique_id)
@@ -222,7 +223,7 @@
         return root;
     }
 
-    if (var->type == NJS_VARIABLE_LET) {
+    if (var->type == NJS_VARIABLE_LET || var->type == NJS_VARIABLE_CONST) {
         goto failed;
     }
 
diff --git a/src/njs_vmcode.c b/src/njs_vmcode.c
index 1a99fc7..9478848 100644
--- a/src/njs_vmcode.c
+++ b/src/njs_vmcode.c
@@ -938,6 +938,10 @@
                 njs_vmcode_error(vm, pc);
                 goto error;
 
+            case NJS_VMCODE_ASSIGNMENT_ERROR:
+                njs_type_error(vm, "assignment to constant variable");
+                goto error;
+
             default:
                 njs_internal_error(vm, "%d has NO retval", op);
                 goto error;
diff --git a/src/njs_vmcode.h b/src/njs_vmcode.h
index f7db975..8a28d99 100644
--- a/src/njs_vmcode.h
+++ b/src/njs_vmcode.h
@@ -62,6 +62,7 @@
     NJS_VMCODE_LET_UPDATE,
     NJS_VMCODE_INITIALIZATION_TEST,
     NJS_VMCODE_NOT_INITIALIZED,
+    NJS_VMCODE_ASSIGNMENT_ERROR,
 
     NJS_VMCODE_ERROR,
 
diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c
index f473dc4..4e46e21 100644
--- a/src/test/njs_unit_test.c
+++ b/src/test/njs_unit_test.c
@@ -9481,6 +9481,27 @@
     { njs_str("function static() {}"),
       njs_str("SyntaxError: Unexpected token \"static\" in 1") },
 
+    { njs_str("var arr = [];"
+              "function fn(one) {"
+              "    var x = one + 1;"
+              "    let y = one + 2;"
+              "    const u = one + 4;"
+              "    {"
+              "        {"
+              "            let z = one + 3;"
+              "            const v = one + 5;"
+              "            function f() {"
+              "                arr.push(one); arr.push(x);"
+              "                arr.push(y);   arr.push(z);"
+              "                arr.push(u);   arr.push(v);"
+              "            }"
+              "            f();"
+              "        }"
+              "    }"
+              "}"
+              "fn(1); arr"),
+      njs_str("1,2,3,4,5,6") },
+
     /* Recursive factorial. */
 
     { njs_str("function f(a) {"
@@ -20009,6 +20030,177 @@
 
     { njs_str("function static() {}"),
       njs_str("SyntaxError: Unexpected token \"static\" in 1") },
+
+    /* const */
+
+    { njs_str("const x"),
+      njs_str("SyntaxError: missing initializer in const declaration") },
+
+    { njs_str("const x = 1; x"),
+      njs_str("1") },
+
+    { njs_str("const x = 1; x = 1"),
+      njs_str("TypeError: assignment to constant variable") },
+
+    { njs_str("function abc() {const x}"),
+      njs_str("SyntaxError: missing initializer in const declaration") },
+
+    { njs_str("const x = [123]; x"),
+      njs_str("123") },
+
+    { njs_str("const x = () => x; x()"),
+      njs_str("[object Function]") },
+
+    { njs_str("const x = (() => x)()"),
+      njs_str("ReferenceError: cannot access to variable before initialization") },
+
+    { njs_str("x; const x = 123"),
+      njs_str("ReferenceError: cannot access to variable before initialization") },
+
+    { njs_str("const x = x + 123"),
+      njs_str("ReferenceError: cannot access to variable before initialization") },
+
+    { njs_str("const x; var x"),
+      njs_str("SyntaxError: \"x\" has already been declared in 1") },
+
+    { njs_str("const x; let x"),
+      njs_str("SyntaxError: \"x\" has already been declared in 1") },
+
+    { njs_str("let x; const x"),
+      njs_str("SyntaxError: \"x\" has already been declared in 1") },
+
+    { njs_str("const x = 1; function x() {}"),
+      njs_str("SyntaxError: \"x\" has already been declared in 1") },
+
+    { njs_str("function x() {} const x = 1"),
+      njs_str("SyntaxError: \"x\" has already been declared in 1") },
+
+    { njs_str("function x() {const x; var x}"),
+      njs_str("SyntaxError: \"x\" has already been declared in 1") },
+
+    { njs_str("function x() {var x; const x}"),
+      njs_str("SyntaxError: \"x\" has already been declared in 1") },
+
+    { njs_str("const x = function f() {const f = 1}"),
+      njs_str("undefined") },
+
+    { njs_str("let res; const x = 1;"
+              "{const x = 2; res = x}"
+              "[x, res]"),
+      njs_str("1,2") },
+
+    { njs_str("let res; const x = 1;"
+              "if (true) {const x = 2; res = x}"
+              "[x, res]"),
+      njs_str("1,2") },
+
+    { njs_str("function func() {return x}"
+              "const x = 123;"
+              "func()"),
+      njs_str("123") },
+
+    { njs_str("function func() {return x}"
+              "func();"
+              "const x = 123"),
+      njs_str("ReferenceError: cannot access to variable before initialization") },
+
+    { njs_str("function func() {return () => x}"
+              "const x = 123;"
+              "func()()"),
+      njs_str("123") },
+
+    { njs_str("function func() {return () => x++}"
+              "const x = 123;"
+              "func()()"),
+      njs_str("TypeError: assignment to constant variable") },
+
+    { njs_str("for (const i = 0; i < 1; i++) {}"),
+      njs_str("TypeError: assignment to constant variable") },
+
+    { njs_str("let res = [];"
+              "for (const n in [1,2,3]) {res.push(n)}"
+              "res"),
+      njs_str("0,1,2") },
+
+    { njs_str("let arr = [], res = [];"
+              ""
+              "for (const n in [1,2,3]) {"
+              "    arr.push(() => n);"
+              "}"
+              ""
+              "for (let n in arr) {"
+              "    res.push(arr[n]());"
+              "}"
+              "res"),
+      njs_str("0,1,2") },
+
+    { njs_str("let arr = [];"
+              ""
+              "for (const n in [1,2,3]) {"
+              "    let n = 1;"
+              "    arr.push(n);"
+              "}"
+              "arr"),
+      njs_str("1,1,1") },
+
+    { njs_str("for (const n in [1,2,3]) {"
+              "    let n = n + 1;"
+              "}"),
+      njs_str("ReferenceError: cannot access to variable before initialization") },
+
+    { njs_str("for (const n in [1,2,3]) {}"
+              "n"),
+      njs_str("ReferenceError: \"n\" is not defined") },
+
+    { njs_str("for (const n in [1,n,3]) {}"),
+      njs_str("ReferenceError: cannot access to variable before initialization") },
+
+    { njs_str("(function() {"
+              "function f() {return x + 1}"
+              "function abc() {f()};"
+              "abc();"
+              "const x = 1;"
+              "}())"),
+      njs_str("ReferenceError: cannot access to variable before initialization") },
+
+    { njs_str("if (false) const x = 1"),
+      njs_str("SyntaxError: const declaration cannot appear in a single-statement context in 1") },
+
+    { njs_str("while (false) const x = 1"),
+      njs_str("SyntaxError: const declaration cannot appear in a single-statement context in 1") },
+
+    { njs_str("for (;;) const x = 1"),
+      njs_str("SyntaxError: const declaration cannot appear in a single-statement context in 1") },
+
+    { njs_str("try {} catch (e) {const e = 1}"),
+      njs_str("SyntaxError: \"e\" has already been declared in 1") },
+
+    { njs_str("let arr = []; const x = 2;"
+              "switch(true) {default: const x = 1; arr.push(x)}"
+              "arr.push(x); arr"),
+      njs_str("1,2") },
+
+    { njs_str("let res;"
+              "switch(true) {case true: const x = 1; default: x = 2; res = x} res"),
+      njs_str("TypeError: assignment to constant variable") },
+
+    { njs_str("const null"),
+      njs_str("SyntaxError: Unexpected token \"null\" in 1") },
+
+    { njs_str("const continue"),
+      njs_str("SyntaxError: Unexpected token \"continue\" in 1") },
+
+    { njs_str("const undefined"),
+      njs_str("SyntaxError: \"undefined\" has already been declared in 1") },
+
+    { njs_str("const a = 1; globalThis.a"),
+      njs_str("undefined") },
+
+    { njs_str("if (false) {x = 2} else {x = 1} const x = 0"),
+      njs_str("ReferenceError: cannot access to variable before initialization") },
+
+    { njs_str("const const"),
+      njs_str("SyntaxError: Unexpected token \"const\" in 1") },
 };