diff --git a/LARAVEL_BEST_PRACTICE.md b/LARAVEL_BEST_PRACTICE.md
new file mode 100644
index 0000000..03fd37e
--- /dev/null
+++ b/LARAVEL_BEST_PRACTICE.md
@@ -0,0 +1,591 @@
+You might also want to check out the [real-world Laravel example application](https://github.com/alexeymezenin/laravel-realworld-example-app)
+
+## Konten
+
+[Prinsip _single responsibility_](#prinsip-single-responsibility)
+
+[Model tebal, _controller_ tipis](#model-tebal-controller-tipis)
+
+[Validasi](#validasi)
+
+[_Business logic_ harus di dalam kelas _services_](#business-logic-harus-di-dalam-kelas-services)
+
+[_Don't repeat yourself_ (DRY)](#dont-repeat-yourself-dry)
+
+[Lebih memilih menggunakan _Eloquent_ daripada menggunakan _Query Builder_ dan query SQL mentah. Lebih memilih _collections_ daripada _array_](#lebih-memilih-menggunakan-eloquent-daripada-menggunakan-query-builder-dan-query-sql-mentah-lebih-memilih-collections-daripada-array)
+
+[_Mass assignment_](#mass-assignment)
+
+[Jangan mengeksekusi kueri dalam _template blade_ dan gunakan _eager loading_ (masalah N + 1)](#jangan-mengeksekusi-kueri-dalam-template-blade-dan-gunakan-eager-loading-masalah-n-1)
+
+[Komentari kode anda, tetapi lebih baik _method_ dan nama variabel yang deskriptif daripada komentar](#komentari-kode-anda-tetapi-lebih-baik-method-dan-nama-variabel-yang-deskriptif-daripada-komentar)
+
+[Jangan letakkan JS dan CSS di _template blade_ dan jangan letakkan HTML apa pun di kelas PHP](#jangan-letakkan-js-dan-css-di-template-blade-dan-jangan-letakkan-html-apa-pun-di-kelas-php)
+
+[Gunakan file _config_, _language_, dan konstanta daripada teks dalam kode](#gunakan-file-config-language-dan-konstanta-daripada-teks-dalam-kode)
+
+[Gunakan _tools_ standar Laravel yang diterima oleh komunitas](#gunakan-tools-standar-laravel-yang-diterima-oleh-komunitas)
+
+[Ikuti konvensi penamaan Laravel](#ikuti-konvensi-penamaan-laravel)
+
+[Gunakan sintaks yang lebih pendek dan lebih mudah dibaca jika memungkinkan](#gunakan-sintaks-yang-lebih-pendek-dan-lebih-mudah-dibaca-jika-memungkinkan)
+
+[Gunakan _IoC Container_ atau _facades_ daripada kelas baru](#gunakan-ioc-container-atau-facades-daripada-kelas-baru)
+
+[Jangan mendapatkan data dari file `.env` secara langsung](#jangan-mendapatkan-data-dari-file-env-secara-langsung)
+
+[Simpan tanggal dalam format standar. Gunakan _accessors_ dan _mutators_ untuk mengubah format tanggal](#simpan-tanggal-dalam-format-standar-gunakan-accessors-dan-mutators-untuk-mengubah-format-tanggal)
+
+[Praktik bagus lainnya](#praktik-bagus-lainnya)
+
+### **Prinsip _single responsibility_**
+
+Kelas dan metode seharusnya hanya memiliki satu tanggung jawab.
+
+Contoh buruk:
+
+```php
+public function getFullNameAttribute(): string
+{
+ if (auth()->user() && auth()->user()->hasRole('client') && auth()->user()->isVerified()) {
+ return 'Mr. ' . $this->first_name . ' ' . $this->middle_name . ' ' . $this->last_name;
+ } else {
+ return $this->first_name[0] . '. ' . $this->last_name;
+ }
+}
+```
+
+Contoh terbaik:
+
+```php
+public function getFullNameAttribute(): string
+{
+ return $this->isVerifiedClient() ? $this->getFullNameLong() : $this->getFullNameShort();
+}
+
+public function isVerifiedClient(): bool
+{
+ return auth()->user() && auth()->user()->hasRole('client') && auth()->user()->isVerified();
+}
+
+public function getFullNameLong(): string
+{
+ return 'Mr. ' . $this->first_name . ' ' . $this->middle_name . ' ' . $this->last_name;
+}
+
+public function getFullNameShort(): string
+{
+ return $this->first_name[0] . '. ' . $this->last_name;
+}
+```
+
+[🔝 Kembali ke konten](#konten)
+
+### **Model tebal, _controller_ tipis**
+
+Masukkan semua logika terkait DB ke model _eloquent_ atau ke dalam kelas repositori jika anda menggunakan _Query Builder_ atau kueri SQL mentah.
+
+Contoh buruk:
+
+```php
+public function index()
+{
+ $clients = Client::verified()
+ ->with(['orders' => function ($q) {
+ $q->where('created_at', '>', Carbon::today()->subWeek());
+ }])
+ ->get();
+
+ return view('index', ['clients' => $clients]);
+}
+```
+
+Contoh terbaik:
+
+```php
+public function index()
+{
+ return view('index', ['clients' => $this->client->getWithNewOrders()]);
+}
+
+class Client extends Model
+{
+ public function getWithNewOrders()
+ {
+ return $this->verified()
+ ->with(['orders' => function ($q) {
+ $q->where('created_at', '>', Carbon::today()->subWeek());
+ }])
+ ->get();
+ }
+}
+```
+
+[🔝 Kembali ke konten](#konten)
+
+### **Validasi**
+
+Pindahkan validasi dari _controller_ ke kelas _request_.
+
+Contoh buruk:
+
+```php
+public function store(Request $request)
+{
+ $request->validate([
+ 'title' => 'required|unique:posts|max:255',
+ 'body' => 'required',
+ 'publish_at' => 'nullable|date',
+ ]);
+
+ ...
+}
+```
+
+Contoh terbaik:
+
+```php
+public function store(PostRequest $request)
+{
+ ...
+}
+
+class PostRequest extends Request
+{
+ public function rules()
+ {
+ return [
+ 'title' => 'required|unique:posts|max:255',
+ 'body' => 'required',
+ 'publish_at' => 'nullable|date',
+ ];
+ }
+}
+```
+
+[🔝 Kembali ke konten](#konten)
+
+### **_Business logic_ harus di dalam kelas _services_**
+
+_Controller_ harus hanya memiliki satu tanggung jawab, jadi pindahkan _business logic_ dari _controller_ ke kelas _service_.
+
+Contoh buruk:
+
+```php
+public function store(Request $request)
+{
+ if ($request->hasFile('image')) {
+ $request->file('image')->move(public_path('images') . 'temp');
+ }
+
+ ...
+}
+```
+
+Contoh terbaik:
+
+```php
+public function store(Request $request)
+{
+ $this->articleService->handleUploadedImage($request->file('image'));
+
+ ...
+}
+
+class ArticleService
+{
+ public function handleUploadedImage($image)
+ {
+ if (!is_null($image)) {
+ $image->move(public_path('images') . 'temp');
+ }
+ }
+}
+```
+
+[🔝 Kembali ke konten](#konten)
+
+### **_Don't repeat yourself_ (DRY)**
+
+Gunakan kembali kode ketika anda bisa. [PSR](#prinsip-single-responsibility) membantu anda menghindari duplikasi. Juga, gunakan kembali _template blade_, _scope eloquent_, dll.
+
+Contoh buruk:
+
+```php
+public function getActive()
+{
+ return $this->where('verified', 1)->whereNotNull('deleted_at')->get();
+}
+
+public function getArticles()
+{
+ return $this->whereHas('user', function ($q) {
+ $q->where('verified', 1)->whereNotNull('deleted_at');
+ })->get();
+}
+```
+
+Contoh terbaik:
+
+```php
+public function scopeActive($q)
+{
+ return $q->where('verified', 1)->whereNotNull('deleted_at');
+}
+
+public function getActive()
+{
+ return $this->active()->get();
+}
+
+public function getArticles()
+{
+ return $this->whereHas('user', function ($q) {
+ $q->active();
+ })->get();
+}
+```
+
+[🔝 Kembali ke konten](#konten)
+
+### **Lebih memilih menggunakan _Eloquent_ daripada menggunakan _Query Builder_ dan query SQL mentah. Lebih memilih _collections_ daripada _array_**
+
+_Eloquent_ memungkinkan anda menulis kode yang dapat dibaca dan _maintainable_. Dan, _Eloquent_ memiliki _built-in tools_ yang bagus seperti _soft deletes_, _events_, _scopes_, dll.
+
+Contoh buruk:
+
+```sql
+SELECT *
+FROM `articles`
+WHERE EXISTS (SELECT *
+ FROM `users`
+ WHERE `articles`.`user_id` = `users`.`id`
+ AND EXISTS (SELECT *
+ FROM `profiles`
+ WHERE `profiles`.`user_id` = `users`.`id`)
+ AND `users`.`deleted_at` IS NULL)
+AND `verified` = '1'
+AND `active` = '1'
+ORDER BY `created_at` DESC
+```
+
+Contoh terbaik:
+
+```php
+Article::has('user.profile')->verified()->latest()->get();
+```
+
+[🔝 Kembali ke konten](#konten)
+
+### **_Mass assignment_**
+
+Contoh buruk:
+
+```php
+$article = new Article;
+$article->title = $request->title;
+$article->content = $request->content;
+$article->verified = $request->verified;
+
+// Add category to article
+$article->category_id = $category->id;
+$article->save();
+```
+
+Contoh terbaik:
+
+```php
+$category->article()->create($request->validated());
+```
+
+[🔝 Kembali ke konten](#konten)
+
+### **Jangan mengeksekusi kueri dalam _template blade_ dan gunakan _eager loading_ (masalah N + 1)**
+
+Contoh buruk (untuk 100 _user_, 101 kueri DB akan dieksekusi):
+
+```blade
+@foreach (User::all() as $user)
+ {{ $user->profile->name }}
+@endforeach
+```
+
+Contoh terbaik (untuk 100 _user_, 2 kueri DB akan dieksekusi):
+
+```php
+$users = User::with('profile')->get();
+
+@foreach ($users as $user)
+ {{ $user->profile->name }}
+@endforeach
+```
+
+[🔝 Kembali ke konten](#konten)
+
+### **Komentari kode anda, tetapi lebih baik _method_ dan nama variabel yang deskriptif daripada komentar**
+
+Contoh buruk:
+
+```php
+if (count((array) $builder->getQuery()->joins) > 0)
+```
+
+Contoh lebih baik:
+
+```php
+// Determine if there are any joins.
+if (count((array) $builder->getQuery()->joins) > 0)
+```
+
+Contoh terbaik:
+
+```php
+if ($this->hasJoins())
+```
+
+[🔝 Kembali ke konten](#konten)
+
+### **Jangan letakkan JS dan CSS di _template blade_ dan jangan letakkan HTML apa pun di kelas PHP**
+
+Contoh buruk:
+
+```javascript
+let article = `{{ json_encode($article) }}`;
+```
+
+Contoh lebih baik:
+
+```php
+
+
+Atau
+
+