documentation
NetchLang 2 Docs
Everything you need to build real desktop apps — beginner friendly, no compromise.
🚀 Beginner Friendly
Reads like plain English. If you can read, you can code in Netch.
🖼️ Real Desktop Apps
Build Windows apps with buttons, windows, dropdowns — no web required.
📦 Package Manager
One command to install community packages. netch pkg install name
🔨 Compile to EXE
Ship a single .exe — no Python needed for your users.
🤖 AI Built-in
Add AI to any app in 3 lines with ainetchintegration.
🎨 Visual Builder
Drag-and-drop IDE — place widgets, generate code automatically.
Installation
Requirements
- Windows 10 or later
- Python 3.8+ (the installer handles this)
Install Everything
Download installer.bat and run it as Administrator. It installs:
- Netch 2 interpreter
- Netch Builder 2 (visual IDE)
- Netch Compiler (compile to .exe)
- Netch Package Manager
- Netch Package Creator
- Netch Launcher (desktop shortcut)
After installing, double-click Netch 2 on your Desktop to open the launcher hub.
Manual Install
python installer.py
Verify
netch version
Hello World
Every Netch 2 file starts with <using.ntch>.
<using.ntch>
print("Hello, World!")
Save as hello.ntch and run:
netch run hello.ntch
Your First Window App
<using.ntch>
use window
window.title("My First App")
window.size(600, 400)
window.center
label("Welcome to NetchLang 2!")
button("Say Hello") action print("Hello!")
Use
netch new myapp to create a starter script from the terminal.Basic Syntax
File Header
<using.ntch> # first line of every .ntch file
Comments
# This is a comment
print("Hello") # inline comment
Variables
name = "Alice"
age = 25
score = 98.5
on = true
Indentation
Use 4 spaces to indent blocks. Tabs work too.
if age > 18
print("Adult")
else
print("Minor")
Variables & Types
| Type | Example | typeof() result |
|---|---|---|
| Text | name = "Alice" | "text" |
| Number | x = 42 | "number" |
| Decimal | pi = 3.14 | "number" |
| Boolean | ok = true | "bool" |
| List | items = list.new("a","b") | "list" |
Type Utils
typeof(x) # "text", "number", "bool", "list"
tonumber("42") # 42
totext(42) # "42"
isnumber("hi") # false
isempty("") # true
Control Flow
If / Else
if score > 90
print("A grade")
else
print("B grade")
While
x = 0
while x < 5
print(x)
x = x + 1
Repeat
repeat 3
print("Hello!")
For Loop
for i from 1 to 10
print(i)
Foreach
fruits = list.new("Apple", "Banana", "Orange")
foreach fruit in fruits
print(fruit)
If Button Clicked
use window
button("Say Hi")
if button("Say Hi") clicked
print("Hi!")
Functions
function greet
print("Hello from a function!")
run(greet)
Functions can access all variables in your script. Define them before calling.
Lists
| Function | What it does |
|---|---|
list.new("a","b","c") | Create a list |
list.add("mylist", val) | Add to end |
list.get("mylist", 0) | Get by index (starts at 0) |
list.length("mylist") | Number of items |
list.remove("mylist", 0) | Remove by index |
list.contains("mylist", val) | Check if item exists |
list.join("mylist", ", ") | Join to text |
colors = list.new("red", "green", "blue")
list.add("colors", "purple")
print(list.length("colors")) # 4
foreach c in colors
print(c)
Strings
| Function | Result |
|---|---|
upper("hello") | "HELLO" |
lower("WORLD") | "world" |
length("netch") | 5 |
contains("netch2","netch") | true |
str.replace("hi","hi","hey") | "hey" |
str.trim(" hi ") | "hi" |
str.reverse("netch") | "hcten" |
str.format("Hi {}","Alice") | "Hi Alice" |
str.starts("hello","he") | true |
str.ends("hello","lo") | true |
str.repeat("ab",3) | "ababab" |
str.count("hello","l") | 2 |
str.index("hello","l") | 2 |
str.split("a,b",",") | list |
Math
| Function | What it does |
|---|---|
math.abs(x) | Absolute value |
math.round(x, 2) | Round to decimal places |
math.floor(x) | Round down |
math.ceil(x) | Round up |
math.sqrt(x) | Square root |
math.power(x, y) | x to the power of y |
math.max(a, b, c) | Largest value |
math.min(a, b, c) | Smallest value |
math.clamp(v, mn, mx) | Keep between min and max |
random(1, 100) | Random whole number |
File System
| Function | What it does |
|---|---|
file.read("path") | Read file as text |
file.write("path","content") | Write to file |
file.append("path","content") | Add line to file |
file.exists("path") | true / false |
file.rename("old","new") | Rename |
file.size("path") | Size in bytes |
openfile("path") | Open with default app |
deletefile("path") | Delete |
copyfile("src","dst") | Copy |
download.file("url","path") | Download from internet |
sys.desktop | Path to Desktop |
sys.homedir | Path to home folder |
Windows
| Command | What it does |
|---|---|
use window | Open the app window |
window.title("name") | Set title |
window.size(800, 600) | Set size |
window.theme("#ffffff") | Background color |
window.center | Center on screen |
window.icon("app.ico") | Set icon |
window.opacity(0.9) | Transparency 0.0–1.0 |
window.resizable(false) | Lock resizing |
window.minimize | Minimize |
window.maximize | Maximize |
window.fullscreen(true) | Fullscreen |
window.always.top(true) | Keep on top |
clear.window | Remove all widgets |
Widgets
| Widget | Code |
|---|---|
| Label | label("text") or label("text","#ff0000") |
| Heading | heading("Big Title") |
| Button | button("Click") action print("clicked") |
| Round Button | cr.button("Click") action print("clicked") |
| Textbox | textbox("mybox", 30, "Placeholder...") |
| Password | passwordbox("mypass") |
| Dropdown | dropdown("mydrop","A","B","C") |
| Checkbox | checkbox("mycheck","Check me") |
| Radio | radiobutton("group","Label","value") |
| Slider | slider("myslider", 0, 100) |
| Listbox | listbox("mylist","Item 1","Item 2") |
| Progress Bar | progressbar("prog", 50) |
| Image | image("photo.png") |
| Separator | separator |
| Spacer | spacer(20) |
| Link | link("Click","https://...") |
| Tabs | tabcontrol("tabs") + addtab("tabs","Tab 1") |
| Webpage | display.webpage("https://example.com") |
Reading Values
getinput("mybox") # textbox / password
getchecked("mycheck") # checkbox → true/false
getradio("group") # radio → selected value
getdropdown("mydrop") # dropdown → selected item
getslider("myslider") # slider → number
getlist("mylist") # listbox → selected item
Dialogs
dialog.info("Title", "Message")
dialog.error("Title", "Message")
answer = dialog.ask("Confirm", "Sure?") # true/false
text = dialog.input("Title", "Prompt:")
file = dialog.file("Open file")
Canvas
| Function | What it does |
|---|---|
canvas.new("c",400,300,"#000") | Create canvas |
canvas.line("c",x1,y1,x2,y2,"#fff",2) | Draw line |
canvas.rect("c",x1,y1,x2,y2,"#color") | Draw rectangle |
canvas.circle("c",x,y,r,"#color") | Draw circle |
canvas.text("c",x,y,"text","#color") | Draw text |
canvas.image("c",x,y,"img.png") | Draw image |
canvas.clear("c") | Clear canvas |
canvas.onclick("c","myfunction") | Click handler |
<using.ntch>
use window
canvas.new("c", 500, 300, "#0d0d14")
canvas.rect("c", 50, 50, 200, 150, "#b8ff00")
canvas.circle("c", 350, 120, 60, "#7c6af7")
canvas.text("c", 250, 20, "My Canvas", "#ffffff")
Dark Mode
<using.ntch>
dark:true
use window
window.title("Dark App")
label("Everything goes dark automatically!")
Use
dark:false to switch back to light at any point.HTTP & Servers
| Function | What it does |
|---|---|
get.request("url") | Fetch from a URL |
send.post("url","key",val) | POST form data |
send.json("url","key",val) | POST JSON |
send.textbox("box","url","field") | Send textbox to server |
connect.server("ws://url") | WebSocket connection |
send.message("text") | Send WebSocket message |
download.file("url","path") | Download a file |
url.open("url") | Open in browser |
browser.open("url") | Embedded browser window |
json.parse("...") | Parse JSON text |
json.make("k",v) | Create JSON text |
Response stored in last.response after any request.
email.send("you@gmail.com", "app-password",
"them@gmail.com", "Subject", "Body")
For Gmail: use an App Password, not your real password. Get one at myaccount.google.com/apppasswords
email.send.html("you@gmail.com", "pass",
"them@gmail.com", "Subject", "<h1>Hello!</h1>")
Sound
sound.play("alert.wav")
sound.stop()
Supports .wav natively. For .mp3, install the pygame package.
Video
video.play("clip.mp4")
video.play("clip.mp4", "myvid")
video.stop("myvid")
Requires:
pip install opencv-python PillowText-to-Speech
tts.say("Hello from NetchLang 2!")
tts.say("Faster", 220)
tts.save("Hello!", "output.mp3")
Requires:
pip install pyttsx3Voice Recognition
text = voice.listen() # online (Google)
text = voice.listen.offline() # offline (PocketSphinx)
print(text)
Requires:
pip install SpeechRecognition pyaudiopdf.create("report.pdf", "My Report")
pdf.heading("Welcome to NetchLang 2")
pdf.text("Made with Netch 2.")
pdf.text("Big text", 18)
pdf.newpage()
pdf.save()
Requires:
pip install reportlabPackage Manager
| Command | What it does |
|---|---|
netch pkg install name | Install a package |
netch pkg remove name | Uninstall |
netch pkg list | List installed |
netch list pkgs all | All packages on GitHub |
netch pkg update | Update all packages |
netch create-pkg | Open Package Creator GUI |
<using.ntch>
importpkg customwindowtitle
# or load everything installed:
import all pkgs
customwindowtitle Package
netch pkg install customwindowtitle
<using.ntch>
importpkg customwindowtitle
use window
windowtitle("title.nframetchpng", "My App")
# with custom close/min/max buttons:
windowtitle("title.nframetchpng", "My App",
"close.png", "min.png", "max.png")
Rename your PNG to
something.nframetchpng. Window is draggable automatically.ainetchintegration Package
netch pkg install ainetchintegration
| Function | What it does |
|---|---|
ai.key("key") | Set Anthropic API key |
ai.system("You are...") | Set AI personality |
ai.ask("question") | Single question → answer |
ai.chat("message") | Chat with history |
ai.clear() | Reset conversation |
ai.history() | Get full conversation |
<using.ntch>
importpkg ainetchintegration
ai.key("your-anthropic-key")
ai.system("You are a helpful assistant")
dark:true
use window
heading("AI Chat")
textbox("q", 40, "Ask something...")
button("Ask AI") action print(ai.ask(getinput("q")))
Get a free API key at console.anthropic.com
controllocalapps Package
netch pkg install controllocalapps
This package manipulates external app windows. You must use the flag system.
<using.ntch>
importpkg controllocalapps
flag -- I_KNOW_WHAT_IM_DOING
confirmation = PRODUCTION_STATE
for warning "THIS MAY INTERFERE WITH APPS" ignore.flag set
app = "C:/myapp.exe"
local.app.system app set to VARIABLE"app"
local.app.launch app
Netch Builder 2
python netch_builder.py
Features
- Drag-and-drop canvas — drag widgets from the palette onto the canvas, move them anywhere
- Double-click to edit — double-click any widget to edit its properties
- Auto code generation — the code updates live as you design
- Code editor mode — switch between visual and code view
- Syntax highlighting for all Netch 2 keywords and functions
- Run from the builder — output shown in the built-in console
- Compile to EXE from the toolbar
- Package Manager integration
- Package Creator integration
Compile to EXE
netch compiletoexe myapp.ntch
netch compiletoexe myapp.ntch --name "My App"
netch compiletoexe myapp.ntch --icon myapp.ico
netch compiletoexe myapp.ntch --output C:/releases
| Flag | What it does |
|---|---|
--output C:/path | Output folder |
--name "App Name" | App name |
--icon myapp.ico | EXE icon |
--folder | Folder instead of single EXE |
Window apps automatically hide the console. Output is ~15-20MB, no Python needed.
CLI Reference
| Command | What it does |
|---|---|
netch run file.ntch | Run a script |
netch new myapp | Create blank script |
netch version | Show version |
netch update | Check for updates |
netch help | All commands |
netch pkg install name | Install package |
netch pkg remove name | Remove package |
netch pkg list | List installed |
netch pkg update | Update all packages |
netch list pkgs all | All GitHub packages |
netch compiletoexe file | Compile to EXE |
netch create-pkg | Open Package Creator |
Plugin System
Load your own Python extensions into any Netch script.
Create a Plugin
# myplugin.py
def say_hello(args):
name = args[0] if args else "World"
print(f"Hello, {name}!")
NETCH_BUILTINS = {"myplugin.hello": say_hello}
Use It
<using.ntch>
plugin.load("myplugin.py")
plugin.call("myplugin.hello", "Alice")