This page provides an overview of the EndBASIC programming language and environment. Most of this text is written in a tutorial-like style, guiding you to accomplish certain tasks. The text is not meant to teach you programming from the ground up, although that would be desirable considering what EndBASIC’s goals are.

Launching the interpreter

EndBASIC is multi-platform and runs on the web and on almost all desktop operating systems, including macOS, Windows, and any Unix derivative such as FreeBSD or Linux. Most features exist in all builds, although there are a few exceptions.

The easiest way to get started is via the web-based interpreter, which you can start by clicking on this button:

Launch interpreter

If you prefer the desktop version, visit the Download page to fetch the right build for your system and follow the instructions provided there.

As a teaser, note that if you end up trying out different versions of the interpreter, the easiest way to move files between them is to use the file-sharing cloud service.

Writing your first program

To create your first program, open up the interpreter, type EDIT and press Enter. This will open up a full-screen text editor where you can start typing your first program. Within it, type the text below and press Esc to return to the command line:

INPUT "What's your name"; name$
PRINT "Hello,"; name$

Once you are back in the command line, try using the LIST command to visualize that the program you typed is stored in the interpreter’s memory, and then use the RUN command to launch your program:

INPUT "What's your name"; name$
PRINT "Hello,"; name$
What's your name? Julio
Hello, Julio

That’s it! You have written and executed your first program!

When the interpreter stops, all state changes made by the program are left untouched. This is useful to illustrate that the program and the interpreter are tightly coupled and helps troubleshoot problems in the program. In other words: any variables defined up to the point where the program stopped are still in memory, so if you type PRINT name$ from the command line, you’ll get back the name that you previously entered.

Because of the side-effects that an executed program leaves behind, the CLEAR exists and lets you reset the interpreter to a clean slate while maintaining your program in memory. (Essentially, RUN does a CLEAR first to ensure that your program isn’t impacted by previous state.) There is also a command called NEW which does the same as CLEAR and also clears the program stored in memory.

To iterate on the program, you can go back to the editor by typing EDIT again, modifying your previous code.

Loading and saving

In the previous section, you wrote your first program—and I suppose you don’t want to lose such a precious creation! To avoid that, you can save your program to disk with the SAVE command, verify that it was saved via the DIR command, and load it back into memory via the LOAD command:

SAVE "hello.bas"
Saved as LOCAL:hello.bas

    Directory of LOCAL:/

    Modified              Size    Name
    2022-06-03 13:08        55    hello.bas

    1 file(s), 55 bytes

LOAD "hello.bas"

Once you have given the program a name, the interpreter will keep track of it until you exit or discard the currently-loaded program via the NEW command. This means that any subsequent SAVE operation can be done without re-entering the program name: simply typing SAVE will update the previously-created file with the new contents.

EndBASIC will try to prevent you from losing your program. For example, if you try to drop the current program with NEW or exit the interpreter before saving your program, EndBASIC will prompt you to confirm your actions.

That said, get in the habit of saving your program frequently. If your program gets stuck, you may need to reboot the interpreter and there is no protection against that.

Getting help

EndBASIC is designed to be self-documenting, and this document does not intend to provide a full reference manual to EndBASIC because this information is already built into the interpreter.

To access the built-in reference documentation, type HELP within the interpreter, which will greet you with a message like this:


    This is EndBASIC 0.9.99.

    Project page at <>
    License Apache Version 2.0 <>

    Top-level help topics

    >> Array functions
    >> Cloud access
    >> Console
    >> Data management
    >> File system
    >> Graphics
    >> Hardware interface
    >> Interpreter
    >> Language reference
    >> Numerical functions
    >> Stored program
    >> String and character functions

    Type HELP followed by the name of a topic for details.
    Type HELP "HELP" for details on how to specify topic names.
    Type LOAD "DEMOS:/TOUR.BAS": RUN for a guided tour.
    Type END or press CTRL+D to exit.

This main help page shows you the available help topics. To get extra help, you need to provide one of those topics to the HELP command. Topic matching is done on a prefix basis, so you can type only part of the topic name. For example, to access the Array functions topic:


    Array functions

    >> LBOUND%    Returns the lower bound for the given dimension of the array.
    >> UBOUND%    Returns the upper bound for the given dimension of the array.

    Type HELP followed by the name of a symbol for details.

And from there, you can also obtain extra information on the subtopics. For example, to get details on the LBOUND% function:


    LBOUND%(array[, dimension%])

    Returns the lower bound for the given dimension of the array.

    The lower bound is the smallest available subscript that can be
    provided to array indexing operations.

    For one-dimensional arrays, the dimension% is optional.  For
    multi-dimensional arrays, the dimension% is a 1-indexed integer.

Pay special attention to the LANG topic, which gives you access to documentation on the language itself. This document replicates some of that information.

Language basics

EndBASIC is an interpreter for a BASIC-like language and is inspired by Amstrad’s Locomotive BASIC 1.1 and Microsoft’s QuickBASIC 4.5. The language itself includes many of the features that you may expect from BASIC, but it can also feel lacking in some scenarios. Please let me know if you find yourself needing a new language construct or new standard library features.

Case sensitivity

EndBASIC is case-insensitive. It is common to write BASIC code all in uppercase, but this is not a requirement. The convention in the EndBASIC interpreter, the documentation, and example code is to write all keywords in uppercase and all identifiers (variable names) in lowercase.

As a tip, note that uppercase keywords make the code look dated because all modern programming languages use lower_snake_case (Rust, C++), camelCase (Java, Python, Go) or PascalCase (C#, Go). Writing your EndBASIC code in lowercase will make it look more modern.

For extra trivia, note that the convention in Visual Basic is to use CamelCase.

Primitive types

EndBASIC is a strongly typed language. Variables are assigned a type at definition time and their type remains immutable throughout their existence. This type is represented as a single-character type annotation appended to the variable names. The type annotation is optional, in which case EndBASIC will infer types, but it must match the type of the variable if present.

Similarly to the note on case sensitivity, the convention in EndBASIC is to almost-always show type annotations next to variable names, but this makes the code look dated. For a more modern look, avoid type annotations unless explicitly required.

The following types are supported:

Double floating point#0.0Numbers with a period
32-bit signed integers%0Numbers from -2,147,483,648 to 2,147,483,647
Strings$""Any text enclosed in double-quotes

Integer literals can also be specified in base form:

BaseInteger literals
Binary&b0101 or &b_0101
Octal&o750 or &o_750
Decimal789, &d789 or &d_789
Hexadecimal&xa10f or &x_a10f

New variables can be defined and declared at assignment time, like in these examples:

bool_var? = TRUE
double_var# = 5.0
integer_var% = 5
string_var$ = "Hello, world!"

Or they can be declared and set to their default values with the DIM command:

DIM b AS BOOLEAN ' b? is set to FALSE.
DIM d AS DOUBLE ' d# is set to 0.0.
DIM i AS INTEGER ' i% is set to 0.
DIM s AS STRING ' s$ is set to "".


EndBASIC supports multidimensional arrays. Arrays are represented as contiguous blocks of memory in row-wise order and all values in the array must be of the same type.

Arrays must be defined with the DIM command and are later accessed using parenthesis (which is unlike most common languages today, which use square brackets for indexing):

' Define a 2-dimensional array (aka matrix) with 5 rows and 3 columns.
DIM arr(5, 3) AS INTEGER

` Assign and access two different positions.
arr(3, 2) = 12345
PRINT arr(1, 1)

Arrays are 0-indexed, which matches QuickBASIC and modern programming practices. There is no support for OPTION BASE nor to specify the lower bound of an array to change this behavior. This might change though, so you are encouraged to use LBOUND% and UBOUND% when iterating over arrays to make your code future-proof:

DIM arr(10)
FOR i = LBOUND%(arr) TO UBOUND%(arr)
    PRINT i, arr(i)


Arithmetic operators

EndBASIC supports the following arithmetic operators:

a + bAddition
a - bSubtraction
a * bMultiplication
a / bDivision (integer or floating point depending on variable types)
a MOD bModulo operation (integer division remainder)
a ^ bExponent operation
-aSign flip

Integers are automatically promoted to doubles when they appear in a floating point expression, and floats are rounded to the closest integer (3.4 becomes 3, but 3.5 becomes 4) when they appear in a context that requires integers.

Comparison operators

EndBASIC supports the following comparison operators:

a = bEquality comparison
a <> bInequality comparison
a < bLess-than comparison
a <= bLess-than or equal to comparison
a > bGreater-than comparison
a >= bGreater-than or equal to comparison

Integers are automatically promoted to doubles when they appear in a floating point expression, and floats are rounded to the closest integer (3.4 becomes 3, but 3.5 becomes 4) when they appear in a context that requires integers.

Logical and bitwise operators

EndBASIC supports the following logical and bitwise operators:

a AND bLogical or bitwise and
a OR bLogical or bitwise or
a XOR bLogical or bitwise exclusive or
NOT aLogical or bitwise negation
a << bBitwise integer left shift
a >> bBitwise integer right shift (signed)

When the operands to these operators are booleans, they perform logical comparisons. There is no automatic coercing of other types into booleans, and there will not be. In particular, this means that something like NOT a in a boolean context is invalid unless a is a boolean.

When the operands to these operators are integers, they perform bitwise operations. The result of these operations are integers, so they cannot be directly used in boolean context. For example, if you are trying to test if a bit is set, you will have to compare the outcome of a bitwise operation against an integer:

IF (a AND &b_0001) <> 0 THEN PRINT "a has the right-most bit set"


All of the previously-described operators can be combined in complex expressions. The following ordering applies when evaluating expressions:

  1. Function calls and array references.
  2. Parenthetical sub-expressions.
  3. Arithmetical sign flip and logical negation.
  4. Arithmetical multiplication, division and modulo.
  5. Arithmetical addition and subtration.
  6. Comparisons.
  7. Logical/bitwise and, or and exclusive or.

Operators of the same priority are applied left-to-right. For example, in 3 - 4 + 5, where both addition and subtraction have the same priority ordering, the subtraction will be done before the addition (as you would expect).

As an example, here is an expression to compute a random number between 500 and 600 and check whether the resulting number is within 500 to 550:

PRINT INT(RND(1) * 100.0) + 500 < 550


EndBASIC supports unconditional jumps to labels and explicitly-assigned line numbers, just like QuickBASIC supports. Labels are words prefixed by the @ sign that appear on a line of their own and line numbers prefix statements just like they do in traditional BASIC implementations.

Here are some examples:

GOTO @first

PRINT "first"
GOTO @second

@second: PRINT "second": GOTO 300

300 PRINT "third"

The @ prefix for label names is an EndBASIC-specific artifact required to resolve parsing ambiguities. This requirement might be relaxed in the future.

EndBASIC does not yet support defining custom functions nor procedures, but it supports GOSUB, which provides an unconditional jump to a target location (using the same syntax as GOTO) and the ability to return to the call site via RETURN.

You can use this feature to implementing rudimentary procedures and functions. For example:

x = 3: y = 4: GOSUB @add
PRINT result

result = x + y


If statements

EndBASIC supports conditional statements (IF) with zero or more alternate branches (ELSE IF and ELSE).

Here is how the most simple construct looks like:

IF 3 < 5 THEN
    PRINT "Three is less than five"

Here is a more advanced construct with multiple alternate branches:

discount# = RND(1)
IF discount# < 0.2 THEN
    PRINT "Meh, a small discount."
ELSEIF discount# < 0.7 THEN
    PRINT "Nice, a good discount!"
    PRINT "Wow, an amazing discount!"

One-line if statements are also supported and have these forms:

IF 3 < 5 THEN PRINT "Less"
IF 3 < 5 THEN PRINT "Less" ELSE PRINT "More"

Multiple choice

Other than for IF/ELSE IF conditionals, EndBASIC also supports to more advanced SELECT CASE multiple choice statement. Here is how it looks like:

INPUT "Enter a number"; a
    CASE 1, 3, 5, 7, 9
        PRINT "Odd"
    CASE 0, 2, 5, 6, 8
        PRINT "Even"
    CASE IS < 0, 10 TO 100
        PRINT "Other cases"
        PRINT "Fallback"


EndBASIC supports a wide variety of loop types.

While loops

While loops are supported via the WHILE and WEND keyword. Here is how they look like:

n% = 0
WHILE n% < 1 OR n% > 10
    INPUT "Enter a number between 1 and 10: ", n%

For loops

For loops are supported via the FOR keyword. For loops iterate over an inclusive range of integers with a default step of 1. For example, the following loop will print numbers 1, 2, 3, 4 and 5:

FOR i% = 1 TO 5
    PRINT i%

The stepping through the range is configurable via the STEP keyword, and this can be both positive and negative. For example, the following loop will print the numbers 10, 8, 6, 4 and 2:

FOR i% = 10 TO 1 STEP -2
    PRINT i%

Both the beginning and end of the range can be arbitrary integer expressions. However, the STEP argument must be an integer literal.

Do loops

Do loops are the most generic type of loop, as they can specify until/while conditions at the start or at the end, or they may omit all conditions to specify an infinite loop.

Here are some examples:

    PRINT "Infinite loop"

    a = a + 1

    a = a + 1

a = 0
DO UNTIL a = 10
    a = a + 1

a = 0
DO WHILE a < 10
    a = a + 1

The EXIT DO statement can be used to terminate a DO loop.

Error handling

Certain errors can be caught and handled programmatically, such as when trying to perform graphical operations on a non-graphical console. This can be achieved with the ON ERROR statement, which configures what to do whenever an error arises. The following options are available:

The ERRMSG function returns the textual representation of the last error that was caught.

Data blocks

A program can specify data values with the DATA statement. These data values can be defined anywhere in the program and can be extracted later on via the READ statement. Here is an example:

DATA 1, 3, 5, 7, 9

    READ i%
    IF i% < 0 THEN EXIT DO

    PRINT i%

DATA 0, 2, 4, 8, -1

User-defined functions and subroutines

EndBASIC supports user-defined functions and subroutines. Here are some examples:

FUNCTION add(n1%, n2%)
    add = n1 + n2

    n = 0
    FOR i = 1 to n2
        n = n + n1
    multiply = n

    PRINT "Your message is "; t
    PRINT add(n1, n2)
    PRINT multiply(n1, n2)

print_all 3, 4, "Hello"

All function and subroutine arguments are currently passed by value. There is no way to pass arrays by reference.

The EndBASIC syntax to set the return value of a function is to assign the value to a variable named like the function. This does not cause the function to return immediately, however,

All variables within functions and subroutines are local by default. To access a global variable, the variable must be defined outside the function with the DIM SHARED keyword:


SUB increment_global
    the_global = the_global + 1

PRINT the_global
PRINT the_global


The EndBASIC console is a hybrid console that offers overlapping textl and graphics. As such, the console exposes two coordinate systems: commands that deal with text use character-based coordinates, and commands that deal with graphics use pixel-based coordinates. Both coordinate systems are 0-indexed and start at the top-left corner of the console.

The graphical console is available by default in the web version of EndBASIC.

Desktop builds have support for the graphical console as well, but they must be built with SDL support. All prebuilt binaries in the Download section have SDL support. Note, however, that to launch the desktop version of EndBASIC with graphics support, you will have to use a command like these:

endbasic --console=graphics             # Default settings.
endbasic --console=graphics:1024x768    # Specific resolution.
endbasic --console=graphics:1920x1080fs # Specific resolution, full screen.

Text manipulation

The EndBASIC text console provides sufficient features to build simple text-based interactive interfaces. These include changing colors, moving the cursor around, and waiting for key presses.

To get started, you can play with the CLS command to clear the screen, the COLOR command to set the foreground and/or background colors of the text, and the LOCATE command to move the cursor to a new position. Note that LOCATE on its own is useless unless it is immediately followed by a PRINT invocation.

To experience these features, type the following string of commands in the console and press Enter:

COLOR 15, 12: CLS: LOCATE 10, 10: PRINT "Hello": LOCATE 0, 15

Interactive interfaces

To build any kind of interactive interface, be it textual or graphical, you will need to wait for key presses. The INPUT command is insufficient for this because it waits for a full line of input. But we can use the INKEY function to poll the keyboard for an input.

For example, see this code to build a loop that waits for a key press and then reacts to it:

PRINT "Press keys to get feedback, or ESC to exit"
k$ = ""
WHILE k$ <> "ESC"
    k$ = INKEY
    IF k$ <> "" THEN
        PRINT "You pressed"; k$
    END IF
    SLEEP 0.01

Rendering graphics

A distinctive feature of EndBASIC is its support for graphics and text in the same console. You can start rendering graphics right from the command line, without having to understand how two separate windows interact with each other or without changing modes.

To get started, play with the GFX_LINE or GFX_RECT commands:

GFX_LINE 0, 0, 100, 100
GFX_RECT 100, 100, 300, 300

Remember that you can access detailed reference information for all available commands within the graphics category by typing HELP "GRAPHICS".

Efficient graphics rendering

Drawing occasional graphics from the console by typing individual commands is a great way of exploring what’s available and understanding how the computer reacts to code, but rendering graphics in this manner is not very efficient: every drawing operation will be flushed to the video card as soon as it is executed, and this is a slow process.

To draw animations in an efficient manner, you must explicitly control when the console’s contents are sent to the screen: in other words, you need to control when every video sync operation happens.

The general idea is that your program needs to render everything first “in memory” and then tell the video driver to paint the results. This can be accomplished via the GFX_SYNC command, which allows us to enable or disable automatic video flushing, and to explicitly flush the video.

Here is a sample program that renders an animation. Pay attention to the way the calls to the GFX_SYNC are done:

' Disable automatic video syncing.

' Loop until any key is pressed.
x% = 0
c% = 0
    ' Clear the screen and render the current frame.
    COLOR c%
    GFX_RECTF x%, 100, x% + 10, 110

    ' Update positions and colors for the next frame.
    c% = (c% + 1) MOD 15
    x% = (x% + 5) MOD 500

    ' Flush the rendered frame to the screen.

    ' Pause until the next frame.
    SLEEP 0.01

' Enable automatic video syncing.

File system

EndBASIC offers a DOS-like interface to access and manipulate files.

Due to the fact that the EndBASIC command line is BASIC, there are a few oddities you will have to get used to when typing commands. The first one is that paths and file names are strings, and as such must be double-quoted. The second one is that arguments to commands must be separated by commas, not just spaces.

Drives and paths

The EndBASIC virtual file system is composed of a bunch of drives, each containing its own collection of files. Drives are mapped to targets, and these targets expose a variety of backend storage services.

Paths in EndBASIC have the general form [DRIVE:][/]FILENAME. Both the drive name and the slash are optional. When all components are present, such as in LOCAL:/FILE.BAS, we have an absolute path that unique identifies a file; when the drive component is missing, such as in FILE.BAS, we have a relative path to the current working directory.

The current working directory can be queried with the CWD command and can be changed via the CD command. For example:


    Working directory: LOCAL:/
    System location: /home/jmmv/Documents/endbasic/

CD "memory:"

    Working directory: MEMORY:/
    No system location available

Directories are not currently supported. This is why the slash in the paths above is optional, but it’s good to get in the habit of specifying it because support for directories will come later.

Drive providers

Drives are mapped to targets, and these targets are backed by virtual file system providers that expose a variety of backend storage services.

The following providers are currently supported:

Target schemeAvailabilityDescription
cloud://userAllExposes the cloud drive of the user. More on this in the Cloud service section.
demos://AllRead-only collection of built-in demo programs.
file:///pathDesktopExposes the /path directory of the local file system. Any subdirectories are ignored.
local://WebProvides a file system backed by the browser’s local storage. Files saved in this provider never leave your machine.
memory://AllMemory-backed file system. Different instances of this provider offer disjoint file systems.

The list of currently-mounted file systems can be queried and modified via the MOUNT command. For example:

MOUNT "cloud://jmmv" AS "jmmv"

    Name      Target
    DEMOS     demos://
    JMMV      cloud://jmmv
    LOCAL     file:///home/jmmv/Documents/endbasic
    MEMORY    memory://

    4 drive(s)

Side-loading files

While EndBASIC provides a built-in editor, the editor is currently quite simplistic. If you find that the editor limits your development speed, you can side-load files into the interpreter. This feature is only available in the desktop version of EndBASIC.

To do this, you can either save files under the default projects location, which typically is ~/Documents/endbasic/, or you can save them under a directory of your choice and then mount that directory inside EndBASIC using the file:// mount target.

For example, say that you create a program outside of EndBASIC:

$ mkdir ~/bas
$ vim ~/bas/example.bas
... edit edit edit ...

Once the file is saved, you can access it like this:

MOUNT "file:///home/jmmv/bas" AS "X"
CD "X:"

    Directory of X:/

    Modified              Size    Name
    2022-06-03 23:37        23    example.bas

    1 file(s), 23 bytes

Cloud service

The EndBASIC service is a simple cloud-based file system that lets you maintain and share your creations with the world, right from the EndBASIC command line.

You can always consume public content without creating an account but, to share your own content, you will need an account first.

Accessing public content

To access a file that was shared publicly by you or someone else, you have two options.

The first option is to tell the web UI to automatically run the program based on a URL of the form:

Replace user with the name of the user that has shared the file and file.bas with the name of the file that was shared. With that, the interpreter will launch, mount the user’s public drive, and run the given file. Try it now: run the endbasic/welcome.bas demo!

The second option is to mount the user’s drive interactively and then investigate its contents. You can do so providing a target of the form cloud://user to the MOUNT command, where user is the name of the user that shared the file. Then, inspect the drive contents with the DIR command and load a file with the LOAD command. Here is a sample session:

MOUNT "cloud://endbasic" AS "e"
CD "e:"

    Directory of E:/

    Modified              Size    Name
    2022-05-27 16:25        40    welcome.bas

    1 file(s), 40 bytes

LOAD "welcome.bas"
PRINT "Welcome to the EndBASIC service!"

When mounting a cloud drive, the contents you see will depend on your credentials. If you are not logged in, all you will see are the user’s public files (if any). If you are logged in, whoever, you will also see any files that the user may have shared directly with you.

Signing up

To create an account, use the SIGNUP command from within the interpreter. You will have to provide basic information for the account, such as a username and a password, and you will also have to provide an email address for account activation (see privacy notes). Here is what you can expect during account creation:


    Let's gather some information to create your cloud account.

    You can abort this process at any time by hitting Ctrl+C and you will
    be given a chance to review your inputs before creating the account.

Username: demo
Password: *********
Retype password: *********

    We also need your email address to activate your account.

    Your email address will be kept on file in case we have to notify you
    of important service issues and will never be made public.  You will
    be asked if you want to receive promotional email messages (like new
    release announcements) or not, and your selection here will have no
    adverse impact in the service you receive.

Email address:
Receive promotional email (y/N)? n

    We are ready to go.  Please review your answers before proceeding.

Username: demo10
Email address:
Promotional email: no
Continue (y/N)? y

    Your account has been created and is pending activation.

    Check your email now and look for a message from the EndBASIC Service.
    Follow the instructions in it to activate your account.  Make sure to
    check your spam folder.

    Once your account is activated, come back here and use LOGIN to get

    If you encounter any problems, please contact

After you complete this process, check your email and look out for a message from the EndBASIC service. You’ll have to click on the link provided within to activate your account, and you must do that before proceeding.

Note the question above to receive promotional emails. If you consent to that, you will receive notifications of new EndBASIC releases and new blog posts via email. I’d appreciate it if you said yes as a mechanism to keep a certain level of engagement in EndBASIC over time. Expect about one email a month at most.

Logging in

Once you have created and activated your account, all you have to do is type LOGIN "username" to log into your account:

LOGIN "demo"
Password: ********

Welcome back, demo! It's good to see you again.
-----  END SERVER MOTD  -----

After a successful log in, the EndBASIC client will mount the CLOUD: drive, which is your personal space to hold files in the cloud. Any files stored in this drive are private to you by default, but they can be shared with others with ease using the SHARE command.


    Directory of CLOUD:/

    Modified              Size    Name
    2021-06-25 13:51       116    thanks.bas
    2021-06-25 13:50       103    welcome.bas

    2 file(s), 219 bytes
    65317 of 65536 bytes free

Uploading a program

Sometimes, it is simpler to develop a program outside of the EndBASIC environment and then side-load it into the interpreter. This is easy to do in the desktop build of EndBASIC because it has direct access to the local file system, but it is hard to do for any file in the cloud.

The way around this is to develop your program locally and then upload it to the cloud. To do this, you will have to do a manual file copy. For example, suppose we want to upload LOCAL:/upload.bas to CLOUD:/upload.bas. We can do so by loading the file into memory and then saving it again, like this:

LOAD "LOCAL:/upload.bas"
SAVE "CLOUD:/upload.bas"
Saved as CLOUD:/upload.bas

Publishing a program

The primary purpose of the EndBASIC cloud service is to let you share your magical creations with the public.

Files saved in cloud drives have reader ACLs that control who can read them. You can give read permissions to individual users, or you can give read permissions to everyone by means of the public pseudo-user.

Suppose we have saved a awesome.bas file in our cloud drive. We can share it with the public like this:

SHARE "CLOUD:/awesome.bas", "public+r"

    You have made the file publicly readable.  As a result, other people
    can now auto-run your public file by visiting:

Note how the SHARE command detects that you have made the file public and will print the URL that users can open to automatically launch your program.

Privacy and security notes

EndBASIC is, right now, a toy project. While I have tried my best to keep the service secure and private, I ask that you do not store any sensitive information in this service.

More specifically:

  1. Your user account and files are stored in a PostgreSQL database managed by Azure. Read the Azure Encryption documentation for more details on what this entails.

  2. I collect high-level metadata on all requests to the cloud service for troubleshooting purposes and basic usage analytics. Details include the contacted API endpoint, the client IP address, and the originating browser agent. The logs do not include the request payloads, but obviously the database does.

  3. The email address collected during the sign-up process will only be used for critical service-related communications by default. These can include notifications of data loss due to the evolving nature of the service. There has only been the need to send one such notification so far, and I expect the volume of these emails to be near zero.

  4. Your email address will never be sold nor given to third-parties. However, as part of giving you service, your email must flow through SendGrid and has is in theory visible to the operators of the PostgreSQL database managed by Azure.

  5. You can opt in to receiving “promotional emails”, and I would appreciate it if you did so. These emails will include notifications of new EndBASIC releases as well as notifications of new blog posts. You can expect about one such message per month on average.

  6. You can always update your account’s information or permanently delete your account and all information associated with it. Contact support and I’ll be happy to assist you; I haven’t had a chance to build those features within the interface yet.

Hardware access

EndBASIC supports limited direct hardware access as a way to play with real-world hardware. Toying with LEDs, buttons, and the like can be a great way of learning how computers work, and is the reason why this support was builtin EndBASIC.

Hardware support is currently limited to the desktop builds for the Raspberry Pi, which you can get from the Download page.


EndBASIC has support to manipulate the GPIO pins of the Raspberry Pi via the family of commands described in HELP "HARDWARE".

As an example, here is how to wait for a physical button press attached to pin number 8:

pressed? = FALSE
WHILE NOT pressed?
    pressed? = GPIO_READ(8)
    SLEEP 0.01

And here is how to flash an LED attached to pin number 18:

state? = TRUE
FOR i = 1 to 10
    GPIO_WRITE 18, state?
    SLEEP 1
    state? = NOT state?


EndBASIC has support for the ST7735s LCD and can display its own console on this 128x128 display. If you have such a device, you can launch EndBASIC like this:

endbasic --console=st7735s

For more information, see Porting the EndBASIC console to an LCD.



The EndBASIC interpreter looks for a file named AUTOEXEC.BAS (all uppercase) in the LOCAL:/ drive at startup time and, if found, will run it before dropping you into the command prompt.

You can create this file from within the interpreter and make it run any commands you like. A common use may be to run LOGIN to automatically log into your cloud account. Or you could use it to customize the appearance of the console by changing its colors.