Every language
14 linguagens, copy-ready. One at a time with syntax highlighting, or all inline.
JSJavaScript
import { appendFile } from 'node:fs/promises';
await appendFile('app.log', 'deploy finished\n', 'utf8');appendFile opens with O_APPEND, writes, and closes per call — fine for occasional lines. For a hot loop, open once with (await open('app.log', 'a')).write(...) and reuse the handle.
TSTypeScript
import { appendFile } from 'node:fs/promises';
const line: string = `deploy finished at ${new Date().toISOString()}\n`;
await appendFile('app.log', line, 'utf8');Identical runtime to the JavaScript version — the type annotation just stops a non-string sneaking into the buffer. It creates the file if it is missing.
GoGo
package main
import "os"
func main() {
f, err := os.OpenFile("app.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644)
if err != nil {
panic(err)
}
defer f.Close()
if _, err := f.WriteString("deploy finished\n"); err != nil {
panic(err)
}
}os.O_APPEND makes the kernel position every write at end-of-file. Pass O_CREATE or a missing file is an error, and never O_TRUNC — that empties the log you came to extend.
RsRust
use std::fs::OpenOptions;
use std::io::Write;
fn main() -> std::io::Result<()> {
let mut file = OpenOptions::new()
.append(true)
.create(true)
.open("app.log")?;
writeln!(file, "deploy finished")?;
Ok(())
}Stdlib only. writeln! appends the '\n' for you — write! does not — and .append(true) maps to O_APPEND rather than seeking once.
PHPPHP
<?php
file_put_contents('app.log', "deploy finished\n", FILE_APPEND | LOCK_EX);FILE_APPEND is the append flag; LOCK_EX takes an advisory lock so concurrent PHP processes don't interleave mid-line. For a stream of lines keep one fopen($fh, 'a') handle open instead of reopening per write.
PyPython
from pathlib import Path
with Path("app.log").open("a", encoding="utf-8") as f:
f.write("deploy finished\n")Mode "a" positions every write at end-of-file ("a+" additionally allows reading). The with block flushes and closes — an abandoned handle can lose buffered lines on exit.
CC
#include <stdio.h>
int main(void) {
FILE *f = fopen("app.log", "a");
if (f == NULL) {
perror("fopen");
return 1;
}
if (fputs("deploy finished\n", f) == EOF) {
fclose(f);
return 1;
}
return fclose(f) == 0 ? 0 : 1;
}Stdio "a" mode creates the file if needed and seeks to end on every write. fputs writes exactly the string — the '\n' is on you — and only fclose (or fflush) drains the buffer.
C++C++
#include <fstream>
int main() {
std::ofstream log("app.log", std::ios::app);
log << "deploy finished\n";
}std::ios::app seeks to end before each write (std::ios::ate seeks once at open, then writes wherever you leave the put pointer). The destructor flushes on scope exit.
C#C#
using System.IO;
File.AppendAllText("app.log", "deploy finished\n");AppendAllText writes exactly what you hand it — the newline is your job; use Environment.NewLine when you want the platform's convention. It reopens per call, so a StreamWriter(new FileStream(..., FileMode.Append)) wins in tight loops.
JvJava
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
public class AppendLine {
public static void main(String[] args) throws IOException {
Files.writeString(
Path.of("app.log"),
"deploy finished" + System.lineSeparator(),
StandardOpenOption.CREATE, StandardOpenOption.APPEND);
}
}StandardOpenOption.APPEND is the flag; without CREATE a missing file throws NoSuchFileException. writeString writes verbatim, so the newline is explicit — System.lineSeparator() for the platform's, "\n" for log files that travel.
SwSwift
import Foundation
let url = URL(fileURLWithPath: "app.log")
let handle = try FileHandle(forWritingTo: url)
try handle.seekToEnd()
try handle.write(contentsOf: Data("deploy finished\n".utf8))
try handle.close()Foundation's String.write(to:) replaces the file even with atomically: false — appending means FileHandle plus seekToEnd() before every write. FileHandle(forWritingTo:) fails if the file doesn't exist; create it first with FileManager.default.createFile(atPath:contents:nil).
KtKotlin
import java.io.File
fun main() {
File("app.log").appendText("deploy finished\n")
}appendText reopens the file per call and encodes as UTF-8; it adds no newline. For many lines, File('app.log').outputStream().bufferedWriter().use { it.appendLine(...) } keeps one handle.
RbRuby
File.open('app.log', 'a') { |f| f.puts 'deploy finished' }Mode 'a' appends; the block closes the handle even on an exception. puts adds the newline that write would omit — a trailing write without one welds the next line onto the last.
ZigZig
const std = @import("std");
pub fn main() !void {
const file = try std.fs.cwd().createFile("app.log", .{ .truncate = false });
defer file.close();
try file.seekFromEnd(0);
try file.writeAll("deploy finished\n");
}createFile defaults to truncate: true — pass .truncate = false to keep existing bytes, then seekFromEnd(0) before writing. std.fs has no append flag in the create options, so the explicit seek is the idiom.