Hello

I am Aditya, a software engineer, writer, and artist.

Investasi yang paling bermanfaat adalah sedekah, karena dengan sedekah Allah akan menambahkan kekayaan kita, dan menjadi bentuk rasa syukur kita terhadap nikmat Allah. Semua sahabat nabi shallallahu ‘alaihi wasallam yang kaya raya, mereka terkenal dengan sedekahnya yang mungkin tidak bisa kita timbang dengan kacamata di masa ini.

Balasan yang Allah berikan kepada kita hanya dengan kita bersedekah jauh lebih besar daripada persentase yang dijanjikan oleh investasi pada manusia.

Bukan berarti tidak boleh berinvestasi, hanya saja ingat bahwa ada sesuatu yang lebih afdhal.

Tulisan ini ditulis untuk mempelajari apa saja opsi investasi yang secara umum tersedia saat ini dan bisa dijangkau oleh individu secara langsung. Ditulis dengan mempelajari sumber-sumber dari:

Jika ada kesalahan, semoga Allah memaafkan saya.

Reksadana (Mutual Funds)

Reksadana adalah instrumen investasi yang menghimpun dana dari berbagai investor untuk dikelola oleh Manajer Investasi. Dalam operasinya, terdapat empat pihak utama: Pemodal, Manajer Investasi, Emiten, dan Bank Kustodian.

Permasalahan Syariah

  1. Pemodal tidak memperoleh bukti kepemilikan langsung atas usaha Emiten, yang dapat merugikan jika terjadi kerugian.

  2. Sistem kompensasi Manajer Investasi dan Bank Kustodian yang berbasis persentase bertentangan dengan prinsip upah tetap dalam syariah Islam.

Contoh perhitungan kompensasi yang membuat Pemodal memiliki banyak kerugian:

  1. Pemodal menyetor dana Rp 100.000.000
  2. Nilai investasi menjadi Rp 110.000.000 setelah satu tahun
  3. Nilai investasi menjadi Rp 90.000.000 setelah dua tahun
  4. Nilai investasi menjadi Rp 120.000.000 setelah tiga tahun

Dalam perhitungan ini, Manajer Investasi dan Bank Kustodian akan mengambil komisi sebesar 10% dari nilai investasi setiap tahun. Terlepas dari untung-rugi Pemodal dan Emiten, Manajer Investasi dan Bank Kustodian akan selalu mendapatkan komisi sebesar 10%.

  1. Tahun 1:

    • Nilai investasi: Rp 110.000.000
    • Komisi: 10% x Rp 110.000.000 = Rp 11.000.000
    • Nilai investasi setelah komisi: Rp 110.000.000 - Rp 11.000.000 = Rp 99.000.000
  2. Tahun 2:

    • Nilai investasi: Rp 90.000.000
    • Komisi: 10% x Rp 90.000.000 = Rp 9.000.000
    • Nilai investasi setelah komisi: Rp 90.000.000 - Rp 9.000.000 = Rp 81.000.000
  3. Tahun 3:

    • Nilai investasi: Rp 120.000.000
    • Komisi: 10% x Rp 120.000.000 = Rp 12.000.000
    • Nilai investasi setelah komisi: Rp 120.000.000 - Rp 12.000.000 = Rp 108.000.000

Dalam hal ini, yang paling dirugikan adalah Pemodal, sedangkan Manajer Investasi dan Bank Kustodian selalu untung.

Karena itu, ada kedzhaliman yang terjadi di proses investasi ini. Apakah kedzhaliman ini menjadikan reksadana dianggap haram secara mutlak atau secara akad investasinya halal, hanya saja terjadi kedzhaliman di pihak manajer investasi dan bank kustodian secara terpisah - saya tidak memiliki pengetahuan yang cukup untuk memberikan kesimpulan yang lebih akurat.

Fatwa DSN-MUI No. 20/DSN-MUI/IV/2001 tentang Pedoman Pelaksanaan Investasi untuk Reksa Dana Syariah


Saham (Stocks)

Saham merupakan bukti kepemilikan atas modal perusahaan yang dapat diperdagangkan di pasar modal.

Permasalahan Syariah

  1. Short-selling dianggap haram karena mengandung unsur spekulasi.
  2. Pembelian saham dapat diperbolehkan dengan syarat:
    • Perusahaan beroperasi dalam bidang yang halal
    • Perusahaan tidak menginvestasikan dana pada instrumen berbasis bunga
    • Perusahaan tidak menggunakan utang berbunga
    • Transaksi dilakukan secara langsung

Jadi, insya Allah selama perusahaannya halal, dan tidak ada spekulasi short-selling, maka investasi pada saham diperbolehkan.

“Allah telah menghalalkan jual beli dan mengharamkan riba.” (Al-Baqarah: 275)

Fatwa DSN-MUI No. 40/DSN-MUI/X/2003 tentang Pasar Modal dan Pedoman Umum Penerapan Prinsip Syariah di Bidang Pasar Modal


Obligasi (Bonds)

Obligasi adalah surat utang yang menyatakan bahwa penerbit obligasi meminjam sejumlah dana kepada pemegang obligasi dan memiliki kewajiban untuk membayar bunga secara berkala serta pokok utang pada waktu yang telah ditentukan.

Permasalahan Syariah

Obligasi konvensional mengandung unsur riba karena adanya bunga yang ditetapkan di awal.

“Hai orang-orang yang beriman, janganlah kamu memakan riba dengan berlipat ganda.” (Ali Imran: 130)


Deposito (Time Deposits)

Deposito adalah produk simpanan bank yang penarikannya hanya dapat dilakukan pada waktu tertentu berdasarkan perjanjian nasabah dengan bank.

Dengan mengendapkan uang di bank, bank akan memutar uang tersebut dan menghasilkan keuntungan, dan nasabah akan mendapatkan keuntungan dari bunga yang diberikan oleh bank.

Permasalahan Syariah

Bank biasanya menawarkan nasabah untuk menyimpan dana di bank dalam waktu tertentu, dan nasabah akan mendapatkan bunga dari bank sesuai jumlah dana yang disimpan dan jangka waktu penyimpanan.

Biasanya, ada deposito yang secara formal ditentukan batas waktunya, dan nasabah tidak bisa menarik dana sebelum waktu yang telah ditentukan.

Dan ada deposito yang tidak ditentukan batas waktunya, dan nasabah bisa menarik dana kapanpun. Biasanya dengan bunga yang lebih rendah.

Keduanya mengandung riba, karena bank menjamin bahwa dana akan selalu ada dan tetap aman. Ditambah nasabah akan mendapatkan bunga

Fatwa DSN-MUI No. 03/DSN-MUI/IV/2000 tentang Deposito


Tabungan Berjangka (Savings Plans)

Tabungan Berjangka memiliki karakteristik yang mirip dengan Deposito, sehingga ketentuan syariahnya mengikuti aturan Deposito dalam Islam, yaitu mengandung riba.


Emas (Gold)

Investasi emas umumnya dilakukan dengan membeli emas fisik, menyimpannya, dan menjualnya saat harga naik atau saat dibutuhkan.

Ketentuan Syariah

Jual beli emas harus memenuhi syarat:

  1. Dilakukan secara tunai
  2. Jika ditukar dengan emas, harus sama ukurannya

“Emas dengan emas, perak dengan perak, … harus sama dan secara tunai.” (HR. Muslim)


Properti (Real Estate)

Investasi properti umumnya dianggap halal dalam Islam. Properti dibeli, disimpan, dan dijual ketika harganya meningkat.

“Dan Allah menghalalkan jual beli.” (Al-Baqarah: 275)


Peer-to-Peer Lending (P2P)

P2P lending adalah proses investasi di mana tidak ada perantara. Pemodal dan Peminjam langsung berhubungan satu sama lain, meskipun mungkin ada platform yang menjadi perantara.

Secara umum, lending/utang-piutang adalah aksi sosial di dalam Islam dan tidak bisa dijadikan tempat untuk mencari keuntungan.

Sehingga, P2P mengandung riba karena meminjamkan uang dengan syarat akan dikembalikan dengan bunga.

“Allah memusnahkan riba dan menyuburkan sedekah.” (Al-Baqarah: 276)


Sukuk (Obligasi Syariah)

Sukuk adalah obligasi yang diterbitkan oleh pemerintah Indonesia berdasarkan prinsip syariah. Pemerintah menawarkan untuk menjual sesuatu, misal tanah; lalu pembeli akan menyewakan tanah tersebut, dan pemerintah akan membayar biaya sewa; diiringi dengan perjanjian bahwa pemerintah akan membeli kembali tanah tersebut pada harga tertentu.

Permasalahan Syariah

Sukuk seperti contoh di atas, mendekati jual-beli ‘Inah.

Di mana penjual menawarkan barang secara terutang dan menjamin akan membelinya kembali, biasanya dengan harga yang lebih rendah.

Contoh:

  1. Penjual memiliki mobil seharga Rp100.000.000
  2. Ditawarkan kepada pembeli dengan harga Rp100.000.000 dibayarkan secara terutang.
  3. Penjual menjamin akan membeli kembali mobil tersebut pada harga tertentu, misal Rp50.000.000 setelah satu tahun.

Jika kita runtut hitungannya, maka akan menjadi:

  1. Penjual mulai dengan asset mobil seharga Rp100.000.000
  2. Pembeli membeli secara terhutang, dia punya Rp100.000.000 dalam bentuk asset mobil. Penjual memiliki Rp100.000.000 dalam bentuk utang.
  3. Setelah satu tahun, penjual membeli kembali mobil dengan harga Rp50.000.000.
  4. Pembeli memiliki uang Rp50.000.000, tapi masih memiliki hutang Rp100.000.000 ke Penjual.
  5. Penjual mendapatkan kembali mobil yang aslinya Rp100.000.000, dan masih memiliki Rp100.000.000 dalam bentuk hutang dari pembeli, dikurangi Rp50.000.000 untuk buyback, maka dia mendapatkan Rp150.000.000.

Bisa dilihat bahwa penjual mendapatkan keuntungan sebesar Rp50.000.000 - yang bisa dikategorikan sebagai riba.


Surat Berharga Negara (Government Securities)

SBN adalah surat berharga yang diterbitkan oleh pemerintah Indonesia. Dia mirip dengan obligasi, di mana pemilik SBN akan mendapatkan pengembalian dana ditambah bunga.

SBN konvensional mengandung unsur riba.

UU No. 19 Tahun 2008 tentang Surat Berharga Syariah Negara


Cryptocurrency

Status cryptocurrency dalam syariah masih diperdebatkan. Beberapa ulama membolehkan dengan syarat tertentu, sementara yang lain melarangnya karena unsur gharar dan spekulasi.

Lebih amannya adalah menghindarinya karena berada di zona abu-abu (syubhat)


Valas (Foreign Exchange)

Perdagangan valas spot diperbolehkan dalam Islam, tetapi forex trading dengan sistem margin atau leverage umumnya dianggap haram karena mengandung unsur riba dan gharar. Unsur spekulasi yang tinggi cenderung mengarahkannya kepada keharaman.

Fatwa DSN-MUI No. 28/DSN-MUI/III/2002 tentang Jual Beli Mata Uang (Al-Sharf)


ORI (Obligasi Ritel Indonesia / Indonesia Retail Bonds)

ORI mirip dengan obligasi yang sudah dijelaskan di atas, di mana pemilik ORI akan mendapatkan pengembalian dana ditambah bunga.

ORI konvensional mengandung unsur riba. Alternatif syariahnya adalah Sukuk Ritel yang diterbitkan pemerintah berdasarkan prinsip syariah.

Fatwa DSN-MUI No. 69/DSN-MUI/VI/2008 tentang Surat Berharga Syariah Negara


Kesimpulan: Opsi Investasi Paling Aman dalam Perspektif Islam

Berdasarkan analisis berbagai opsi investasi dari perspektif Islam, beberapa pilihan yang umumnya dianggap paling aman dan sesuai dengan prinsip syariah adalah:

  1. Sedekah
  2. Properti Syariah
  3. Saham Syariah
  4. Emas dan Perak
  5. Bisnis dan Kemitraan Etis

Dalam mempertimbangkan opsi-opsi ini, penting untuk mengingat beberapa prinsip kunci:

  • Menghindari Riba (bunga)
  • Menghindari Gharar (ketidakpastian berlebihan) dan Maysir (perjudian)
  • Berinvestasi dalam Aktivitas Halal
  • Berbagi Risiko

Sangat penting untuk melakukan penelitian menyeluruh, mencari nasihat dari ahli keuangan Islam, dan tetap mengikuti fatwa dan keputusan terkini dari ulama atau lembaga Islam terpercaya seperti Majelis Ulama Indonesia (MUI).

Tulisan ini dibuat untuk membantu memahami opsi investasi yang umum ada di masa sekarang, dan bagaimana posisi investasi tersebut berdasarkan prinsip syariah.


Wallahu a’lam bish-showab - semoga Allah menjelaskan kepada kita apa yang belum diketahui.

I am not a Java/Kotlin expert, so there might be some mistakes on my understanding. This was just my understanding of the problem and solution.

I’ve been working on a JetBrains IDE plugin recently, and I ran into a problem with conflicting dependencies. The documentation for developing a JetBrains plugin is there, but its lacking examples of common pitfalls and how to avoid them. This dependency conflict is one of them. I discovered the solution after spending hours trying to figure out why my plugin won’t work, and I found a solution on the Slack channel of JetBrains Platform (which probably gonna be removed soon as the Slack is on free tier and it has limits on how many messages it will retain).

I really like JetBrains IDEs, and I really wish that the documentation for plugin development could be better.

In my case, I need to add ktor client to do HTTP requests, and kotlinx serialization to serialize and deserialize JSON. These libraries requires kotlinx-coroutines-core, but it conflicts with the one that JetBrains IDE bundles. So when there’s a code from JetBrains that requires you to provide a class from kotlinx-coroutines-core, it’s gonna break because now you are passing a class from your own version of kotlinx-coroutines-core instead of the one the IDE bundles.

dependencies {
    val ktor_version = "2.3.12"
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.7.2")
    implementation("io.ktor:ktor-client-content-negotiation:$ktor_version")
    implementation("io.ktor:ktor-serialization-kotlinx-json-jvm:$ktor_version")
    implementation("io.ktor:ktor-client-cio:$ktor_version")
}

Above, I have a few dependencies that are pulling in conflicting versions of the kotlinx-coroutines-core library.

At first, you won’t notice any issue. But the moment you need to use a class from kotlinx-coroutines-core to be called from JetBrains SDK, i.e. Service, you will start to feel the pain.

@Service(Service.Level.PROJECT)
class MyProjectService(project: Project, cs: CoroutineScope) {

    init {
        thisLogger().info(MyBundle.message("projectService", project.name))
        thisLogger().warn("Don't forget to remove all non-needed sample code files with their corresponding registration entries in `plugin.xml`.")
    }

    fun getRandomNumber() = (1..100).random()
}

The cs: CoroutineScope parameter above is from kotlinx.coroutines.CoroutineScope. Now, in compile time, it will use the external library version of kotlinx-coroutines-core pulled by the ktor library, not the one that JetBrains IDE bundles. However, at runtime, JetBrains will complains that it doesn’t understand the CoroutineScope class.

These issues are scattered all over the places, when you need to dispatch a new coroutine, JetBrains will complains that it doesn’t understand how to dispatch it because it was compiled against a different version of kotlinx-coroutines-core than what it bundles.


Special thanks to Riv, Ilan Shamir, and Philip Wedemann, Jaakko Nakaza - their conversation on Slack helped me to figure out the solution.

The solution is to exclude the conflicting library in configurations.runtimeClasspath.


configurations.runtimeClasspath {
    exclude("org.jetbrains.kotlin", "kotlin-stdlib")
    exclude("org.jetbrains.kotlin", "kotlin-stdlib-common")
    exclude("org.jetbrains.kotlin", "kotlin-stdlib-jdk8")
    exclude("org.jetbrains.kotlinx", "kotlinx-coroutines")
    exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core")
    exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-jdk8")
}

This will ensure that the JetBrains IDE will use its own bundled library for kotlinx-coroutines-core instead of the one pulled by ktor.

So far, this solution works for me. If you have a better solution, please let me know.

Rewriting The Site Again
engineering

I originally wrote my website using raw HTML, CSS, and JavaScript. I was expecting a lot of interactive content at that time, but then realized I don’t really have that much time to write and it actually put a burden on me when trying to write.

Then I moved into Nuxt, it was a bigger experiment with focus on visuals and animation. But again, instead of focusing my time on writing, I got distracted by the idea of having a fully featured blog with all the glitters and golds.

Now, I decided to just make it plain white, simple, raw, and decided to use Astro to reduce the amount of JavaScript I use.

Will there be a fourth time? Who knows.

Embracing Improvements
engineering

Some of my coworker might remember that few years ago I was strongly against Tailwind CSS in one of our project. The reason was that our design system wasn’t rigid enough for us to be able to use Tailwind, and that we ended writing new css class for each of our deviations. The choice between,

<div class="my-element flex items-center bg-white"/>
.my-element {
    margin-left: 34px;
}
// or
.my-element {
    margin-left: 34px;
    @apply flex items-center bg-white;
}

and

<div class="my-element"/>
.my-element {
    margin-left: 34px;
    display: flex;
    align-items: center;
    background: white;
}

was obvious that if we ended up with a lot of deviations by creating our own class, let’s just stick with raw CSS.

We were using scoped CSS at that time, so we don’t really care about name colission. If the choice was between the robust name of BEM and Tailwind, we’d probably go with Tailwind and just bear the pain of deviations.


Tailwind was still on its early days that time, it was slow to use, and there was no support for arbitrary values using square brackets. I kept pushing my team to stop using Tailwind, let’s stick with CSS as we don’t have a consistent design system.

But fast-forward, Tailwind improved a lot. There were improvements going on with Tailwind. JIT is a thing, compile speed was better, extending the configuration has become easier, and the support for arbitrary values allowed us to have an escape hatch without maintaining another CSS file.

So I decided to embrace Tailwind and start advocating to use it for new projects. Even when the designer decided to nudge that margin into 171px, we’d have no problem as we can just m-[171px]


Where Tailwind Shine Tailwind shines when we have a consistent design system and that the designer properly plan their design tokens and enforcing discipline. This way, a developer can model their Tailwind configuration to match the design principles. When thing goes south, deviating is just two keystrokes away (or 14 if you use m-[1234567890px]).


When there’s an improvement, we should embrace it. A lot of developers got too fixated by certain technologies that they missed good things happening at the other side of the fence.

However, it does not mean that we got the green pass to just use everything in our project. I experienced it first hand in an open source project where they implement all the possible tooling without considering how it’d impact the performance and development flow. I stopped contributing when the package.json dependencies reached 60 or something—for a website that just shows data from a database without any user inputs.


Remember, it’s always about the product, the team, and the workflow. It’s the technology that should adapt with those, not the other way around.

Building a one-page landing page using React, Tailwind, Gatsby, SCSS, React Router, Redux, SQL in JS, and Web Assembly? Enjoy the 1-minute build time, I guess?

On Nested CSS
engineering

Have you ever stumbled upon a code that looks like this?

.card {

  /*
   Some lengthy css definitions
   it has
   to
   be
   lengthy
    */

  &-header {
    /*
    Some lengthy css definitions
    it has
    to
    be
    lengthy
     */
  }

  &-footer {
    /*
   Some lengthy css definitions
   it has
   to
   be
   lengthy
    */

    &-links {
      /*
       Some lengthy css definitions
       it has
       to
       be
       lengthy
        */

      &-link {

        /*
       Some lengthy css definitions
       it has
       to
       be
       lengthy
        */
      }
    }
  }

  &-body {
    /*
       Some lengthy css definitions
       it has
       to
       be
       lengthy
        */
  }

  .article {
    /*
       Some lengthy css definitions
       it has
       to
       be
       lengthy
        */

    &-content {
      /*
       Some lengthy css definitions
       it has
       to
       be
       lengthy
        */

    }
  }
}

<div class="card">
    <header class="card-header"></header>
    <div class="card-body">
        <article class="article">
            <p class="article-content"></p>
        </article>
    </div>
    <footer class="card-footer">
        <nav class="card-footer-links">
            <a href="#" class="card-footer-links-link"></a>
        </nav>
    </footer>
</div>

Seems harmless, right? But beyond this seemingly innocent code, hides a tiny bit of complications that could be harmful to development.

The Complexities

The example above is written in Less syntax, which is similar to SCSS; both encourage us to use the & symbol to represent the parent selector. Even though it might not be semantically correct, we’ve been using the & to write less code. Why bother writes card-header when you can just &-header right?

However, using parent selector as a solution to write less code leads to several tiny problems that don’t break your code, but add additional overload to you, as a developer.

Now, because you wrote card-header as &-header, there’s no way you can accurately search for card-header anymore. You probably have a lot of others &-header for other class, then you’d end up with multiples of &-header to parse from instead of just searching for card-header.

Some IDE might be smart enough to resolve card-header when you do “Go to Declaration” command and resolve it for you. It means your IDE will need to index it properly so that it knows the card-header that you wanted to open is indexed to card.css -> .card -> &-header - this additional indexing; when small, will not cause issues. But an unnecessary overhead as well, just because we dev have high-performing machine, we tend to ignore this additional indexing process.

WebStorm helps will properly go to the declaration when its used on places that WebStorm knows it’s going to be a class name. If it’s an arbitrary string, it won’t resolve, and you’d have to resort to search.

The inverse is not possible, if you want to find where does &-header being used, cmd+clicking on the class name nor the Find Usages will help you resolve this. You’d have to manually type the full selector to search its usage.

Broken Autocompletion

Some IDE might be able to understand the &-header that you have can be autocompleted when you start typing card- on the class property of your element. Just like the search above, it requires proper indexing on the IDE to know this.

Again, WebStorm supports this, but when it’s on an arbitrary string where WebStorm doesn’t index it. Good luck with remembering the full name because search is not that helpful in this situation

Broken Reading

When you are deep into the CSS file that you are editing, and all you can see is &-links, you will need an additional overhead to remember what’s the current parent selector that you’re working on? Then, you need to scroll up to know, “oh, it was the .a-very-long-class-name-already”.

Code can automatically parse and understand what’s the & currently refers to, but you as a human, will need to process that first, remember it again, and then know what & currently resolve to.

WebStorm again, supports showing a breadcrumb to know where are you currently at.

Broken Refactoring

Changing a &-header into &-headers might seem easy, but if your IDE doesn’t properly index it, you’d need to ensure that you’re only changing that specific parent selector and not breaking other class that follows the same structure.

Even WebStorm can’t refactor nested-selector at the moment.

When to Actually Use It?

Nested selector is helpful, but it’s not there to help you abbreviate the parent selector. It’s there to help you write less but in a way that doesn’t involve abbreviation.

Parent Modifiers

When you want to add hover, active, focus, etc. effects. Nested selector really helps you, and it helps you without additional overhead to understand what the parent is because it’s always going to be that one parent only.


.button {
  &:hover {

  }

  &:focus {

  }

  &:disabled {

  }
}

Above, you can understand that the nested selector affects the parent and not to create a new child selector. You can also use it to write BEM-like modifiers like below.

.button {
  &__primary {

  }

  &__secondary {

  }
}

The aim of the nested selector is to modify the parent, and not introduce a new children.

Scoping

You can use nested selector to have a better refined scope of what you want to change. For example, you have a reusable class called .card, and you have .main-card-grid where you want to show the card as a grid with additional shadows.

.card {

}

.main-card-grid {
  .card {
    box-shadow: 0 2px 4px #0001;
  }
}

Without nesting, you’d have to type .main-card-grid .card, but nesting still help us write less but without resolving to use parent selector as a way to abbreviate things.

Summary

We can utilize nested selector on things that don’t introduce additional overhead and issues that we might encounter in the future. Modifiers and scoping are a good reason to use it. Using it to abbreviate, the parent selector will introduce several problems in the future.

A good rule of thumb when working with nested selector is that if it’s semantically a different element, and it just happens to have similar class name because it’s a children of that specific class name, you’d better of on writing a separate selector for it.

.card {

  .card-header{

  }
  
}

// or to avoid nested hell
.card-header {
  
}

Above, card and card-header is an entirely different element, with different looks, and different semantics; so it doesn’t make sense to use nested selector other than we just want to abbreviate the card part.

You can parse it easily, you can refactor it easily, and you can search it easily.

A better alternative is to use CSS module, where you no longer need to worry about name collision.

Thoughts

What are your thoughts about nested selector? What problems that you encountered while using it so far? Now that native nested selector is here, what’s stopping us from writing pure CSS?