Docs

Storage

Appwrite Storage allows you to manage files in your project. You can use it to store images, videos, documents, and other files for your projects. It provides APIs to upload, download, delete, and list files. Not only that Appwrite storage service provides APIs to manipulate images. Using the preview endpoint, you can crop, resize, rotate, add borders and border-radius and select the desired output format for your image. The preview API also allows you to change your image's quality, format, or compression, including WebP support for maximum optimization of your network bandwidth.

Buckets

Storage buckets are similar to collections in the Databases service. The difference is buckets also provide more power to decide what kinds of files, what sizes you want to allow in that bucket, whether or not to encrypt the files, scan with antivirus, and more. Let's look at how we can create a bucket and configure it to your needs.

Create Bucket

You can create your bucket from your Appwrite project's dashboard, using any of our server-side SDKs, or directly using our REST API authenticated using an API Key. To create a bucket from the Appwrite Console, access your Storage dashboard from your project's left navigation panel. Click Add Bucket button and choose your bucket's name. You can also set a custom ID for your bucket instead of an auto-generated ID for convenience. This will create a new bucket and take you to its settings page, where you can configure various options for your bucket.

You can manage your buckets programmatically using one of Appwrite's Server SDKs or REST API paired with an API Key. You can manage files with both Server and Client side.

Permissions

The Storage Service allows you to configure permissions at both the bucket level and the file level. When a user has the appropriate type of access permissions granted at either the bucket or the file level, they will be able to access the file. If the permission field is left empty, no one can access the file.

File Level Permissions

File level permissions grant access to individual files. File level permissions are only enabled if File Security is enabled in the settings of your bucket.

Bucket Level Permissions

Bucket level permissions apply to every file in the bucket.

More Bucket Configurations

Storage buckets have many configuration options, including the type and maximum size of files in the bucket, whether encryption or anti-virus is enabled, and the compression algorithm to use. If you look at the bucket settings or the REST API example above, you can find these configurations. Let's look at what those are:

Parameter Description
allowedFileExtensions This parameter allows you to provide a list of file extensions that will be accepted into the bucket.
maximumFileSize This parameter allows you to set the maximum size of a file that a bucket accepts. The buckets will accept any file less than or equal to the size provided here.
encryption This parameter allows you to configure whether or not the files inside the bucket will be encrypted. We don't encrypt files bigger than 20MB.
antivirus This parameter allows you to configure whether or not the files being added inside the bucket be scanned by antivirus. We don't scan files bigger than 20MB.

You can learn more about storage buckets and APIs you can use to manage storage buckets from our Storage documentation. Now that we know how to create and configure buckets for our applications, let's look at how to manage files using the storage service.

Create File

After you create a bucket or have navigated to bucket details, you can access the Files tab so you can upload, view, delete and update files in the bucket using the Appwrite project's dashboard. You can also perform all those operations from Appwrite's client SDK, server SDKs, and REST APIs as long as you have the proper permission.

When you are in the Files tab, you can click Add File and select a file to upload. If the bucket is configured to accept the file type and size you are uploading, your file will be uploaded, and you will see the file in the list of files.

You can also upload files programmatically using our SDKs:

  • Web

    import { Client, Storage } from "appwrite";
    
    const client = new Client()
        .setEndpoint('https://cloud.appwrite.io/v1')
        .setProject('[PROJECT_ID]');
    
    const storage = new Storage(client);
    
    const promise = storage.createFile(
        '[BUCKET_ID]',
        ID.unique(),
        document.getElementById('uploader').files[0]
    );
    
    promise.then(function (response) {
        console.log(response); // Success
    }, function (error) {
        console.log(error); // Failure
    });
                
  • Flutter

    import 'package:appwrite/appwrite.dart';
    
    void main() { // Init SDK
      final client = Client()
        .setEndpoint('https://cloud.appwrite.io/v1')
        .setProject('[PROJECT_ID]');
    
      final storage = Storage(client);
    
      final file = await storage.createFile(
        bucketId: '[BUCKET_ID]',
        fileId: ID.unique(),
        file: InputFile.fromPath(path: './path-to-files/image.jpg', filename: 'image.jpg'),
      );
    }
  • Android

    import io.appwrite.Client
    import io.appwrite.services.Storage
    
    suspend fun main() {
        val client = Client(applicationContext)
            .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
            .setProject("[PROJECT_ID]") // Your project ID
    
        val storage = Storage(client)
    
        val file = storage.createFile(
            bucketId = "[BUCKET_ID]",
            fileId = ID.unique(),
            file = File("./path-to-files/image.jpg"),
        )
    }
  • Apple

    import Appwrite
    
    func main() async throws {
        let client = Client()
          .setEndpoint("https://cloud.appwrite.io/v1")
          .setProject("[PROJECT_ID]")
    
        let storage = Storage(client)
    
        let file = try await storage.createFile(
            bucketId: "[BUCKET_ID]",
            fileId: ID.unique(),
            file: InputFile.fromBuffer(yourByteBuffer,
                filename: "image.jpg",
                mimeType: "image/jpeg"
            )
        )
    }
  • GraphQL

    POST /v1/storage/buckets/{bucketId}/files HTTP/1.1
    Content-Type: multipart/form-data; boundary="cec8e8123c05ba25"
    Content-Length: *Length of your entity body in bytes*
    X-Appwrite-Project: [PROJECT_ID]
    
    --cec8e8123c05ba25
    Content-Disposition: form-data; name="operations"
    
    { "query": "mutation CreateFile($bucketId: String!, $fileId: String!, $file: InputFile!) { storageCreateFile(bucketId: $bucketId, fileId: $fileId, file: $file) { id } }", "variables": { "bucketId": "[BUCKET_ID]", "fileId": "[FILE_ID]", "file": null } }
    --cec8e8123c05ba25
    Content-Disposition: form-data; name="map"
    
    { "0": ["variables.file"] }
    --cec8e8123c05ba25
    Content-Disposition: form-data; name="0"; filename="file.txt"
    Content-Type: text/plain
    
    File content.
    
    --cec8e8123c05ba25--

When you are trying to upload any files above 5MB, you will need to upload them in chunks for better reliability and performance. If you're using an Appwrite SDK, this is handled automatically. If you're not using an SDK, you can learn more about file handling in the REST API docs.

File Input

Every language and platform handles file inputs differently. This section documents the expected input type of each SDK. Where applicable, Appwrite provides a InputFile class to accept multiple file sources, like paths, buffers, streams, or plain text.

Client SDK

  • Web

    The Appwrite Web SDK expects a File object for file creation. This is most commonly associated with DOM file inputs.

    For example, for the input tag <input type="file" id="uploader" />, you would call create file like this:

    const promise = storage.createFile(
        '[BUCKET_ID]',
        ID.unique(),
        document.getElementById('uploader').files[0]
    );
  • Flutter

    The Appwrite Flutter SDK expects an InputFile class for file inputs.

    Method Description
    InputFile.fromPath(path: [PATH], filename: [NAME], contentType: [MIME TYPE]) Used to upload files from a provided path, filename and contentType are optional. Used for Flutter apps on mobile and desktop.
    InputFile.fromBytes(bytes: [BYTE LIST], filename: [NAME], contentType: [MIME TYPE]) Used to upload files from a byte list, contentType is optional. Used for Flutter apps on web
  • Android

    The Appwrite Android SDK expects an InputFile class for file inputs.

    Method Description
    InputFile.fromPath(path: String) Used to upload files from a provided path.
    InputFile.fromFile(file: File) Used to upload files from a File object.
    InputFile.fromBytes(bytes: ByteArray, filename: String, mimeType: String) Used to upload files from a ByteArray object. Specify the file MIME type using the mimeType param.
  • Apple

    The Appwrite Apple SDK expects an InputFile class for file inputs.

    Method Description
    InputFile.fromPath(_ path: String) Used to upload files from a provided path.
    InputFile.fromData(_ data: Data, filename: String, mimeType: String) Used to upload files from a Data object. Specify the file MIME type using the mimeType param.
    InputFile.fromBuffer(_ buffer: ByteBuffer, filename: String, mimeType: String) Used to upload files from a NIO Buffer object. Specify the file MIME type using the mimeType param.

Server SDK

  • Node.js

    The Appwrite NodeJS SDK expects an InputFile class for file inputs.

    Method Description
    InputFile.fromPath(filePath, filename) Used to upload files from a provided path.
    InputFile.fromBuffer(buffer, filename) Used to upload files from a Buffer object.
    InputFile.fromBlob(blob, filename) Used to upload files from a Blob object.
    InputFile.fromStream(stream, filename, size) Used to upload files from a Readable Stream object.
    InputFile.fromPlainText(content, filename) Used to upload files in plain text. Expects a string encoded in UTF-8.
  • PHP

    The Appwrite PHP SDK expects an InputFile class for file inputs.

    Method Description
    InputFile.withPath(string $path, ?string $mimeType = null, ?string $filename = null) Used to upload files from a provided path.
    InputFile.withData(string $data, ?string $mimeType = null, ?string $filename = null) Used to upload files from a string.
  • Python

    The Appwrite Python SDK expects an InputFile class for file inputs.

    Method Description
    InputFile.from_path(path) Used to upload files from a provided path.
    InputFile.from_bytes(bytes) Used to upload files from an array of bytes.
  • Ruby

    The Appwrite Ruby SDK expects an InputFile class for file inputs.

    Method Description
    InputFile.from_path(path) Used to upload files from a provided path.
    InputFile.from_string(string) Used to upload files from a String.
    InputFile.from_bytes(bytes) Used to upload files from an array of bytes.
  • Deno

    The Appwrite Deno SDK expects an InputFile class for file inputs.

    Method Description
    InputFile.fromPath(filePath, filename) Used to upload files from a provided path.
    InputFile.fromBuffer(buffer, filename) Used to upload files from a Uint8Array object.
    InputFile.fromPlainText(content, filename) Used to upload files in plain text. Expects a string encoded in UTF-8.
  • Dart

    The Appwrite Dart SDK expects an InputFile class for file inputs.

    Method Description
    InputFile.fromPath(path: [PATH], filename: [NAME], contentType: [MIME TYPE]) Used to upload files from a provided path, filename and contentType are optional.
    InputFile.fromBytes(bytes: [BYTE LIST], filename: [NAME], contentType: [MIME TYPE]) Used to upload files from a byte list, contentType is optional.
  • Kotlin

    The Appwrite Kotlin SDK expects an InputFile class for file inputs.

    Method Description
    InputFile.fromPath(path: String) Used to upload files from a provided path.
    InputFile.fromFile(file: File) Used to upload files from a File object.
    InputFile.fromBytes(bytes: ByteArray, filename: String, mimeType: String) Used to upload files from a ByteArray object. Specify the file MIME type using the mimeType param.
  • Swift

    The Appwrite Swift SDK expects an InputFile class for file inputs.

    Method Description
    InputFile.fromPath(_ path: String) Used to upload files from a provided path.
    InputFile.fromData(_ data: Data, filename: String, mimeType: String) Used to upload files from a Data object. Specify the file MIME type using the mimeType param.
    InputFile.fromBuffer(_ buffer: ByteBuffer, filename: String, mimeType: String) Used to upload files from a NIO Buffer object. Specify the file MIME type using the mimeType param.

Image Manipulation

Another great built-in feature of Appwrite is the image manipulation feature. With Appwrite Storage's preview endpoint you can manipulate resolution, add borders and the border-radius, add background-color, set the opacity for the image, and get the image in the appropriate output format.

This enables a wide range of possibilities! You can manipulate images resolution to display appropriately on responsive websites. You can also adjust the image border, background color, and border-radius to match the theming of your application. The Appwrite Storage also allows you to change the format and compression of your images for network transfer optimization and to help you speed your application. You can do all that without caring about how the image was originally uploaded.

Below you can find all the different parameters offered by the preview endpoint to manipulate the image.

Parameter Description
height Set the height of the output image in pixels, the image will be resized keeping the aspect ratio intact. Accepts integer between 0-4000
width Set the width of the output image in pixels, the image will be resized keeping the aspect ratio intact. Accepts integer between 0-4000
gravity The gravity while cropping the image providing either width, height or both. Accepts any of: center, top-left, top, top-right, left, right, bottom-left, bottom, bottom-right
quality Set the quality of the output image. Accepts integer between 0-100, where 100 is the highest quality.
borderWidth Set a border with given width in pixels to the output image. Accepts integer between 0-100
borderColor Set a border-color for the output image. Accepts any valid Hex color value without the leading #.
borderRadius Set a border-radius in pixels. Accepts an integer between 0-4000.
opacity Set opacity for the output image. Accepts a float value between 0-1, where 0 makes it transparent. Only works with output format supporting alpha channel like png.
rotation Rotate the output image by a degree. Accepts an integer between -360 to 360.
background Set a background-color. Accepts any valid Hex color value without the leading #. Only works with output format supporting alpha channel like png.
output Set the output image format. If not provided, will use the original image's format. Supported formats are: jpg, jpeg, png, gif and webp

Downloading and Streaming with Range

Appwrite supports streamed downloads using the HTTP range header to gracefully handle large files. If you are using our SDKs or console, nothing is different. Even if you want to download the whole file at once, even if you use the REST endpoint directly, there isn't any difference. However, if you want to get only a part of a file from storage, you can supply the range header and the server will respond with an appropriate chunk of the file.