diff --git a/docs/advanced/compiler-annotations.md b/docs/advanced/compiler-annotations.md
index f3b923bb..80dbfcb8 100644
--- a/docs/advanced/compiler-annotations.md
+++ b/docs/advanced/compiler-annotations.md
@@ -306,109 +306,6 @@ declare function myFunction(n: number): [number, number];
Note that if any overloaded signature of a function implementation has the annotation, all array/tuple return values will unpacked in the transpiled output.
-## @vararg
-
-**Target elements:** `(declare) interface or type`
-
-Indicates that an array-like type represents a Lua vararg expression (`...`) and should be transpiled to that when used in a spread expression. This is useful for forwarding varargs instead of wrapping them in a table and unpacking them.
-
-**Example**
-
-
-
-```typescript
-function varargWrapUnpack(...args: string[]) {
- console.log(...args);
-}
-```
-
-```lua
-function varargWrapUnpack(self, ...)
- local args = ({...})
- print(unpack(args))
-end
-```
-
-
-
-
-
-```typescript
-/** @vararg */
-interface Vararg extends Array {}
-
-function varargForward(...args: Vararg) {
- console.log(...args);
-}
-```
-
-```lua
-function varargForward(self, ...)
- print(...))
-end
-```
-
-
-
-This can be used to access the file-scope varargs as well.
-
-**Example**
-
-
-
-```typescript
-declare const arg: Vararg;
-console.log(...arg);
-const [x, y] = [...arg];
-```
-
-```lua
-print(...)
-local x, y = ...
-```
-
-
-
-To also support tuple-typed rest parameters, you can define the type like this:
-
-**Example**
-
-```typescript
-/** @vararg */
-type Vararg = T & { __luaVararg?: never };
-
-function varargForward(...args: Vararg<[string, number]>) {}
-```
-
-**_Warning_**
-
-TypeScriptToLua does not check that the vararg expression is valid in the context it is used. If the array is used in a spread operation in an invalid context (such as a nested function), a deoptimization will occur.
-
-**Example**
-
-
-
-```typescript
-function outerFunction(...args: Vararg) {
- function innerFunction() {
- console.log(...args);
- }
- innerFunction();
-}
-```
-
-```lua
-function outerFunction(self, ...)
- local args = {...}
- local function innerFunction(self)
- print(unpack(args))
- end
- innerFunction(_G)
-end
-```
-
-
-
## Deprecated
:::warning
@@ -851,3 +748,153 @@ print(tbl.get(foo)); // print(tbl[foo])
tbl.set(1, "baz"); // tbl[1] = "baz"
print(tbl.length()); // print(#tbl)
```
+
+### @vararg
+
+
+
+**Target elements:** `(declare) interface or type`
+
+Indicates that an array-like type represents a Lua vararg expression (`...`) and should be transpiled to that when used in a spread expression. This is useful for forwarding varargs instead of wrapping them in a table and unpacking them.
+
+**Example**
+
+
+
+```typescript
+function varargWrapUnpack(...args: string[]) {
+ console.log(...args);
+}
+```
+
+```lua
+function varargWrapUnpack(self, ...)
+ local args = ({...})
+ print(unpack(args))
+end
+```
+
+
+
+
+
+```typescript
+/** @vararg */
+interface Vararg extends Array {}
+
+function varargForward(...args: Vararg) {
+ console.log(...args);
+}
+```
+
+```lua
+function varargForward(self, ...)
+ print(...))
+end
+```
+
+
+
+This can be used to access the file-scope varargs as well.
+
+**Example**
+
+
+
+```typescript
+declare const arg: Vararg;
+console.log(...arg);
+const [x, y] = [...arg];
+```
+
+```lua
+print(...)
+local x, y = ...
+```
+
+
+
+To also support tuple-typed rest parameters, you can define the type like this:
+
+**Example**
+
+```typescript
+/** @vararg */
+type Vararg = T & { __luaVararg?: never };
+
+function varargForward(...args: Vararg<[string, number]>) {}
+```
+
+**_Warning_**
+
+TypeScriptToLua does not check that the vararg expression is valid in the context it is used. If the array is used in a spread operation in an invalid context (such as a nested function), a deoptimization will occur.
+
+**Example**
+
+
+
+```typescript
+function outerFunction(...args: Vararg) {
+ function innerFunction() {
+ console.log(...args);
+ }
+ innerFunction();
+}
+```
+
+```lua
+function outerFunction(self, ...)
+ local args = {...}
+ local function innerFunction(self)
+ print(unpack(args))
+ end
+ innerFunction(_G)
+end
+```
+
+
+
+**Upgrade Instructions**
+
+`@vararg` is no longer required to prevent vararg parameters from being wrapped in a table. The ellipsis operator will now automatically be used if the parameter is used in a spread expression.
+
+Example:
+
+
+
+```ts
+function varargForward(...args: string[]) {
+ console.log(...args);
+}
+```
+
+```lua
+function varargForward(...)
+ print(...)
+end
+```
+
+
+
+However, if the parameter is accessed as an array or tuple, it will be wrapped in a table.
+
+Example:
+
+
+
+```ts
+function varargAccess(...args: string[]) {
+ console.log(args[0]);
+}
+```
+
+```lua
+function varargAccess(...)
+ local args = {...}
+ print(args[1])
+end
+```
+
+
+
+Note that are a few cases where the parameter will still be wrapped in a table, even if a spread expression is used, in order to generate correctly functioning Lua.
diff --git a/docs/advanced/language-extensions.md b/docs/advanced/language-extensions.md
index 68c084a2..3f4e9aea 100644
--- a/docs/advanced/language-extensions.md
+++ b/docs/advanced/language-extensions.md
@@ -321,3 +321,37 @@ declare namespace IdDictionary {
IdDictionary.set(dict, id, "bar");
console.log(IdDictionary.get(dict, id));
```
+
+## $vararg Constant
+
+Lua allows use of the ellipsis operator (`...`) to access command line arguments passed when executing a script file. To access this from Typescript, you can use the `$vararg` constant in a spread expression.
+
+Example:
+
+
+
+```ts
+console.log(...$vararg);
+```
+
+```lua
+print(...)
+```
+
+
+
+When run:
+
+
+
+```
+> lua myscript.lua foo bar
+```
+
+```
+foo bar
+```
+
+
+
+Use of `$vararg` is only allowed at file scope, and only in a spread expression (`...$vararg`).