# Can I define a custom IO wrapper type that works with all IO functions like print?

**URL:** <https://discourse.julialang.org/t/can-i-define-a-custom-io-wrapper-type-that-works-with-all-io-functions-like-print/133652>\
**Category:** General Usage\
**Tags:** question, io\
**Created:** [November 4, 2025, 1:01pm UTC](https://discourse.julialang.org/t/can-i-define-a-custom-io-wrapper-type-that-works-with-all-io-functions-like-print/133652 "2025-11-04T13:01:04Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![BYH-1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/byh-1/32/219262_2.png) [@BYH-1](https://discourse.julialang.org/u/BYH-1)\
**Post date:** [November 4, 2025, 1:01pm UTC](https://discourse.julialang.org/t/can-i-define-a-custom-io-wrapper-type-that-works-with-all-io-functions-like-print/133652/1 "2025-11-04T13:01:04Z")

</div>

I’d like to define a new type that wraps an existing IO object, for example:

```julia
struct MyIOWrapper <: IO
    inner::IO
end

Base.write(io::MyIOWrapper, x) = 
    # custom write logic here

#Base.unsafe_write is also defined

```

Since Julia doesn’t have a C++ style “base class” mechanism, I’m wondering:

if I define this type as a subtype of IO and implement basic methods like write and unsafe\_write, will other built-in functions that operate on IO objects — such as print, println, show — automatically work with my custom type?

In other words, does Julia’s IO interface fully support user-defined subtypes like this?Can user-defined IO subtypes be made fully compatible with all functions that expect an IO?

Thanks!

---

<div class="post-metadata">

**Author:** ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)\
**Post date:** [November 4, 2025, 1:36pm UTC](https://discourse.julialang.org/t/can-i-define-a-custom-io-wrapper-type-that-works-with-all-io-functions-like-print/133652/2 "2025-11-04T13:36:36Z")

</div>

> [@BYH-1](#):
>
> if I define this type as a subtype of IO and implement basic methods like write and unsafe\_write, will other built-in functions that operate on IO objects — such as print, println, show — automatically work with my custom type?

That is the usual way to do things in julia, yes. However, I don’t think a minimal interface for `IO` has been specified. It might suffice with defining a `write`, possible a `read`. The usual io-functions takes an option `io::IO` first argument, so whenever they call a `write` they will use your `write`.

---

<div class="post-metadata">

**Author:** ![BYH-1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/byh-1/32/219262_2.png) [@BYH-1](https://discourse.julialang.org/u/BYH-1)\
**Post date:** [November 4, 2025, 1:51pm UTC](https://discourse.julialang.org/t/can-i-define-a-custom-io-wrapper-type-that-works-with-all-io-functions-like-print/133652/3 "2025-11-04T13:51:26Z")

</div>

Thanks! Am I right that there’s no official guideline or minimal required set of methods for a user-defined subtype in Julia — it’s mostly about following the conventions used by Base?

If that’s the case, wouldn’t it be difficult for developers to know which functions should be implemented or extended when defining a new type?

---

<div class="post-metadata">

**Author:** ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)\
**Post date:** [November 4, 2025, 2:10pm UTC](https://discourse.julialang.org/t/can-i-define-a-custom-io-wrapper-type-that-works-with-all-io-functions-like-print/133652/4 "2025-11-04T14:10:00Z")

</div>

> [@BYH-1](#):
>
> If that’s the case, wouldn’t it be difficult for developers to know which functions should be implemented or extended when defining a new type?

Yes, that’s a recurrent topic. Julia lacks a formal interface/trait mechanism. It’s quite difficult to implement properly without stumbling into problems. Instead it’s common to use “duck-typing” (if it walks like a duck, and talks like a duck, it is a duck). I.e., just add enough low level methods for the things one wants to work.

For some of the abstract types an interface has been defined in the manual, but not for `IO`:

> **[Interfaces · The Julia Language](https://docs.julialang.org/en/v1/manual/interfaces/)**
>
> Documentation for The Julia Language.

---

<div class="post-metadata">

**Author:** ![BYH-1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/byh-1/32/219262_2.png) [@BYH-1](https://discourse.julialang.org/u/BYH-1)\
**Post date:** [November 4, 2025, 2:29pm UTC](https://discourse.julialang.org/t/can-i-define-a-custom-io-wrapper-type-that-works-with-all-io-functions-like-print/133652/5 "2025-11-04T14:29:53Z")

</div>

Thanks for your help! I roughly read through the content, and it seems those interfaces are more like conventions rather than strict constraints.
