Dart Runtime

Host Dart CLI applications on Witchly.host. Deploy from Git, install pub packages, and run server-side Dart or Nyxx bots.

Dart Runtime

The Dart egg runs server-side Dart applications — CLI tools, backend services (shelf, Alfred, Serverpod), or Discord bots via Nyxx. Witchly runs the stable Dart SDK.

When to pick Dart

  • You already write Flutter and want code sharing between client and server.
  • You want a type-safe, AOT-compiled language with fast cold starts.
  • You’re building a Discord bot and prefer Dart over Node/Python/Elixir.

Quick deploy

  1. dash.witchly.hostDeployLanguagesdart generic.
  2. On the Startup tab, set Git Repo Address to your repo URL.
  3. Start.

Startup flow

if [[ -d .git ]] && [[ {{AUTO_RESET}} == "1" ]]; then git reset --hard; fi
if [[ -d .git ]] && [[ {{AUTO_UPDATE}} == "1" ]]; then git pull; fi
dart pub get
dart run

dart run executes the default entrypoint defined in pubspec.yaml or bin/main.dart.

Variables reference

VariablePurpose
GIT_ADDRESSGit repo URL
BRANCHGit branch
USER_UPLOAD1 to skip clone
AUTO_UPDATE1 to git pull on each start
AUTO_RESET1 to git reset --hard before pulling (discards local changes)
USERNAME, ACCESS_TOKENPrivate repo credentials

pubspec.yaml setup

name: my_bot
environment:
  sdk: ^3.4.0

dependencies:
  nyxx: ^6.0.0

executables:
  my_bot:
    path: bin/main.dart

With executables defined, dart run finds bin/main.dart automatically.

HTTP server example (shelf)

// bin/main.dart
import 'dart:io';
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as io;

void main() async {
  final port = int.parse(Platform.environment['SERVER_PORT']!);
  final handler = Pipeline().addMiddleware(logRequests()).addHandler(_echo);
  await io.serve(handler, '0.0.0.0', port);
  print('Listening on :$port');
}

Response _echo(Request request) => Response.ok('Hello from Dart!');
# pubspec.yaml dependencies
dependencies:
  shelf: ^1.4.0

Discord bot with Nyxx

// bin/main.dart
import 'dart:io';
import 'package:nyxx/nyxx.dart';

void main() async {
  final bot = await Nyxx.connectGateway(
    Platform.environment['DISCORD_TOKEN']!,
    GatewayIntents.guildMessages | GatewayIntents.messageContent,
  );

  bot.onMessageCreate.listen((event) async {
    if (event.message.content == '!ping') {
      await event.message.channel.sendMessage(MessageBuilder(content: 'pong'));
    }
  });
}

AOT compile for production

dart run uses the JIT (fast iteration, higher memory use). For production, compile AOT:

dart compile exe bin/main.dart -o bin/my_bot

Then change the startup to ./bin/my_bot. Smaller footprint, faster startup, no Dart SDK overhead at runtime.

Troubleshooting

  • “Could not find main” — make sure bin/main.dart exists and has a void main() { ... }.
  • pub get fails on private dependency — configure pub credentials in ~/.pub-cache/credentials.json via SFTP, or use Git dependencies with SSH.
  • Port already in use — you’re binding to a port other than $SERVER_PORT; only the allocated port is accessible externally.

Next steps