|
| 1 | +--- |
| 2 | +title: "Code Reuse with Taubyte Libraries" |
| 3 | +author: Zaoui Amine |
| 4 | +featured: true |
| 5 | +draft: false |
| 6 | +tags: |
| 7 | + - tutorials |
| 8 | + - libraries |
| 9 | + - code-reuse |
| 10 | + - serverless |
| 11 | + - golang |
| 12 | + - wasm |
| 13 | +image: |
| 14 | + src: /blog/images/taubyte-libraries.png |
| 15 | + alt: Code Reuse with Taubyte Libraries |
| 16 | +summary: Libraries in Taubyte let you keep serverless function code in separate repositories, share logic across multiple functions, and control access more precisely. Learn how to create libraries and use them both as function sources and as imported dependencies. |
| 17 | +date: 2026-01-14T12:40:00Z |
| 18 | +categories: [Hand-on Learning] |
| 19 | +--- |
| 20 | + |
| 21 | +When building serverless functions in Taubyte, you have two options for organizing your code: inline code within your project, or **libraries**—separate repositories that can be shared and reused across functions and projects. |
| 22 | + |
| 23 | +Libraries in Taubyte enable you to: |
| 24 | + |
| 25 | +- Keep serverless function code **outside the main repository** |
| 26 | +- **Share code** across multiple functions |
| 27 | +- Control access more precisely with separate repositories |
| 28 | +- Build reusable components for your entire platform |
| 29 | + |
| 30 | +## Prerequisites |
| 31 | + |
| 32 | +Before you begin, make sure you have: |
| 33 | + |
| 34 | +1. **A local Taubyte cloud running** with Dream: |
| 35 | + - Install Dream: `npm install -g @taubyte/dream` |
| 36 | + - Start your local cloud: `dream new multiverse` |
| 37 | + - Connect to it at [console.taubyte.com](https://console.taubyte.com) by selecting the **blackhole** network |
| 38 | + |
| 39 | +2. **A Taubyte project created** in the console (if you haven't created one yet, see [Creating Your First Taubyte Project](/blog/posts/creating-your-first-taubyte-project)) |
| 40 | + |
| 41 | +## Creating a Library |
| 42 | + |
| 43 | +From the sidebar, navigate to **Libraries** and click the **+** button. |
| 44 | + |
| 45 | +1. **Name your library** (e.g., `my-shared-lib`) |
| 46 | +2. Choose to either: |
| 47 | + - **Import** an existing library using its repository URL |
| 48 | + - **Generate** a new repository with starter code |
| 49 | +3. Click **Generate** to create a new library |
| 50 | + |
| 51 | +This creates a GitHub repository with template code. |
| 52 | + |
| 53 | +### Pushing Changes |
| 54 | + |
| 55 | +Click the **green button** in the bottom right to push: |
| 56 | + |
| 57 | +1. **Important**: Copy and save the **Library GitHub ID**—you'll need it for builds |
| 58 | +2. Enter a commit message |
| 59 | +3. Click **Finish** |
| 60 | +4. Skip the build for now (the library isn't in use yet) |
| 61 | + |
| 62 | +## Adding Code to Your Library |
| 63 | + |
| 64 | +Click the **open icon** to view your library's repository on GitHub. |
| 65 | + |
| 66 | +Open the template file (e.g., `empty.go`) and replace its content: |
| 67 | + |
| 68 | +```go |
| 69 | +package lib |
| 70 | + |
| 71 | +import ( |
| 72 | + "github.com/taubyte/go-sdk/event" |
| 73 | +) |
| 74 | + |
| 75 | +//export ping |
| 76 | +func ping(e event.Event) uint32 { |
| 77 | + h, err := e.HTTP() |
| 78 | + if err != nil { |
| 79 | + return 1 |
| 80 | + } |
| 81 | + |
| 82 | + h.Write([]byte("PONG")) |
| 83 | + return 0 |
| 84 | +} |
| 85 | +``` |
| 86 | + |
| 87 | +Commit the changes directly on GitHub. |
| 88 | + |
| 89 | +## Using a Library as a Function Source |
| 90 | + |
| 91 | +Now let's create a function that uses this library as its code source. |
| 92 | + |
| 93 | +Navigate to **Functions** and click **+**: |
| 94 | + |
| 95 | +| Field | Value | |
| 96 | +|-------|-------| |
| 97 | +| Name | Your function name | |
| 98 | +| Timeout | `1s` | |
| 99 | +| Memory | `10MB` | |
| 100 | +| Method | `GET` | |
| 101 | +| Domain | `GeneratedDomain` | |
| 102 | +| Path | `/lib/ping` | |
| 103 | +| **Source** | Select your library (e.g., `my-shared-lib`) | |
| 104 | +| Entry Point | `ping` | |
| 105 | + |
| 106 | +Push the changes, ignore any inline code repo updates, commit and finish. Notice the source is now your library. |
| 107 | + |
| 108 | +### Building the Library |
| 109 | + |
| 110 | +In your terminal, build both the library and configuration: |
| 111 | + |
| 112 | +```bash |
| 113 | +# Build the specific library using its ID and fullname |
| 114 | +dream inject push-specific -u blackhole -rid <library-github-id> -fn <library-fullname> |
| 115 | + |
| 116 | +# Build all configuration |
| 117 | +dream inject push-all |
| 118 | +``` |
| 119 | + |
| 120 | +> **Note**: Use your own repository ID and fullname. If you didn't save them, navigate to the library, click on it, then switch to YAML to find them. Another way is to open the config repository and find them in `libraries/<library-name>.yaml`. |
| 121 | +
|
| 122 | +### Testing |
| 123 | + |
| 124 | +Once both builds finish, go back to the console, click the **lightning icon** next to your function. You should see the `PONG` message. |
| 125 | + |
| 126 | +## Using a Library as a Dependency |
| 127 | + |
| 128 | +Libraries can also be imported as dependencies within other functions. This is powerful for creating reusable utility modules. |
| 129 | + |
| 130 | +### Step 1: Add a Utility Function to Your Library |
| 131 | + |
| 132 | +In your library repository, click **Add file** > **Create new file**. Name the file `add.go` and add the following code: |
| 133 | + |
| 134 | +```go |
| 135 | +package lib |
| 136 | + |
| 137 | +//export add |
| 138 | +func add(a, b uint32) uint64 { |
| 139 | + return uint64(a) + uint64(b) |
| 140 | +} |
| 141 | +``` |
| 142 | + |
| 143 | +Click **Commit changes...** to commit and push. |
| 144 | + |
| 145 | +### Step 2: Create a Function that Imports the Library |
| 146 | + |
| 147 | +Navigate to **Functions** and click **+**. Click **Template Select**, select **Go** and **empty**, then close the template modal. |
| 148 | + |
| 149 | +Configure the function: |
| 150 | + |
| 151 | +| Field | Value | |
| 152 | +|-------|-------| |
| 153 | +| Name | `add` | |
| 154 | +| Timeout | `1s` | |
| 155 | +| Memory | `10MB` | |
| 156 | +| Method | `GET` | |
| 157 | +| Domain | `GeneratedDomain` | |
| 158 | +| Path | `/lib/add` | |
| 159 | +| Entry Point | `doAdd` | |
| 160 | + |
| 161 | +Click on **Code** to switch to the code tab, then paste the following code: |
| 162 | + |
| 163 | +```go |
| 164 | +package lib |
| 165 | + |
| 166 | +import ( |
| 167 | + "fmt" |
| 168 | + "strconv" |
| 169 | + |
| 170 | + "github.com/taubyte/go-sdk/event" |
| 171 | + http "github.com/taubyte/go-sdk/http/event" |
| 172 | +) |
| 173 | + |
| 174 | +// Import `add` the library |
| 175 | +// |
| 176 | +//go:wasmimport libraries/<library-name> add |
| 177 | +func add(a, b uint32) uint64 |
| 178 | + |
| 179 | +func getQueryVarAsUint32(h http.Event, varName string) uint32 { |
| 180 | + varStr, err := h.Query().Get(varName) |
| 181 | + if err != nil { |
| 182 | + panic(err) |
| 183 | + } |
| 184 | + |
| 185 | + varUint, err := strconv.ParseUint(varStr, 10, 32) |
| 186 | + if err != nil { |
| 187 | + panic(err) |
| 188 | + } |
| 189 | + |
| 190 | + return uint32(varUint) |
| 191 | +} |
| 192 | + |
| 193 | +//export doAdd |
| 194 | +func doAdd(e event.Event) uint32 { |
| 195 | + h, err := e.HTTP() |
| 196 | + if err != nil { |
| 197 | + return 1 |
| 198 | + } |
| 199 | + |
| 200 | + // call the library function |
| 201 | + sum := add(getQueryVarAsUint32(h, "a"), getQueryVarAsUint32(h, "b")) |
| 202 | + |
| 203 | + // send the result over http |
| 204 | + h.Write([]byte(fmt.Sprintf("%d", sum))) |
| 205 | + |
| 206 | + return 0 |
| 207 | +} |
| 208 | +``` |
| 209 | + |
| 210 | +> **Note**: `libraries/<library-name>` is resolved within the context of the application the function is part of, then globally. In this case the function is global so the library is only resolved globally. |
| 211 | +
|
| 212 | +Push the changes. |
| 213 | + |
| 214 | +### Step 3: Build and Test |
| 215 | + |
| 216 | +Trigger a build for the configuration changes: |
| 217 | + |
| 218 | +```bash |
| 219 | +dream inject push-all |
| 220 | +``` |
| 221 | + |
| 222 | +Test the function with curl: |
| 223 | + |
| 224 | +```bash |
| 225 | +curl 'http://your-domain.blackhole.localtau:14529/lib/add?a=40&b=2' |
| 226 | +``` |
| 227 | + |
| 228 | +Output: |
| 229 | +``` |
| 230 | +42 |
| 231 | +``` |
| 232 | + |
| 233 | +## Library vs. Inline Code: When to Use Each |
| 234 | + |
| 235 | +| Use Case | Recommendation | |
| 236 | +|----------|----------------| |
| 237 | +| Quick prototypes | Inline code | |
| 238 | +| Shared utilities | Library | |
| 239 | +| Multiple functions same logic | Library | |
| 240 | +| Strict access control | Library (separate repo) | |
| 241 | +| Complex applications | Library | |
| 242 | +| Simple HTTP handlers | Either works | |
| 243 | + |
| 244 | + |
| 245 | +## Conclusion |
| 246 | + |
| 247 | +You've now learned how to: |
| 248 | + |
| 249 | +1. **Create libraries** for code organization |
| 250 | +2. **Use libraries as function sources** for cleaner architecture |
| 251 | +3. **Import libraries as dependencies** for code reuse |
| 252 | + |
| 253 | +Libraries are a powerful way to keep your codebase organized as your project grows. They enable sharing logic across your entire platform while maintaining clear ownership and access control. |
| 254 | + |
| 255 | +Next, learn how to [host websites](/blog/posts/hosting-websites-taubyte) on your Taubyte cloud. |
| 256 | + |
0 commit comments