text:
Is this number a prime?
Believe it or not, we do not yet have a code golf challenge for a simple primality test. While it may not be the most interesting challenge, particularly for "usual" languages, it can be nontrivial in many languages.
Rosetta code features lists by language of idiomatic approaches to primality testing, one using the Miller-Rabin test specifically and another using trial division. However, "most idiomatic" often does not coincide with "shortest." In an effort to make Programming Puzzles and Code Golf the go-to site for code golf, this challenge seeks to compile a catalog of the shortest approach in every language, similar to "Hello, World!" and Golf you a quine for great good!.
Furthermore, the capability of implementing a primality test is part of our definition of programming language, so this challenge will also serve as a directory of proven programming languages.
Task
Write a full program that, given a strictly positive integer n as input, determines whether n is prime and prints a truthy or falsy value accordingly.
For the purpose of this challenge, an integer is prime if it has exactly two strictly positive divisors. Note that this excludes 1, who is its only strictly positive divisor.
Your algorithm must be deterministic (i.e., produce the correct output with probability 1) and should, in theory, work for arbitrarily large integers. In practice, you may assume that the input can be stored in your data type, as long as the program works for integers from 1 to 255.
Input

If your language is able to read from STDIN, accept command-line arguments or any other alternative form of user input, you can read the integer as its decimal representation, unary representation (using a character of your choice), byte array (big or little endian) or single byte (if this is your languages largest data type).
If (and only if) your language is unable to accept any kind of user input, you may hardcode the input in your program.
In this case, the hardcoded integer must be easily exchangeable. In particular, it may appear only in a single place in the entire program.
For scoring purposes, submit the program that corresponds to the input 1.

Output
Output has to be written to STDOUT or closest alternative.
If possible, output should consist solely of a truthy or falsy value (or a string representation thereof), optionally followed by a single newline.
The only exception to this rule is constant output of your language's interpreter that cannot be suppressed, such as a greeting, ANSI color codes or indentation.
Additional rules

This is not about finding the language with the shortest approach for prime testing, this is about finding the shortest approach in every language. Therefore, no answer will be marked as accepted.
Submissions in most languages will be scored in bytes in an appropriate preexisting encoding, usually (but not necessarily) UTF-8.
The language Piet, for example, will be scored in codels, which is the natural choice for this language.
Some languages, like Folders, are a bit tricky to score. If in doubt, please ask on Meta.
Unlike our usual rules, feel free to use a language (or language version) even if it's newer than this challenge. If anyone wants to abuse this by creating a language where the empty program performs a primality test, then congrats for paving the way for a very boring answer.
Note that there must be an interpreter so the submission can be tested. It is allowed (and even encouraged) to write this interpreter yourself for a previously unimplemented language.
If your language of choice is a trivial variant of another (potentially more popular) language which already has an answer (think BASIC or SQL dialects, Unix shells or trivial Brainfuck derivatives like Headsecks or Unary), consider adding a note to the existing answer that the same or a very similar solution is also the shortest in the other language.
Built-in functions for testing primality are allowed. This challenge is meant to catalog the shortest possible solution in each language, so if it's shorter to use a built-in in your language, go for it.
Unless they have been overruled earlier, all standard code-golf rules apply, including the http://meta.codegolf.stackexchange.com/q/1061.

As a side note, please don't downvote boring (but valid) answers in languages where there is not much to golf; these are still useful to this question as it tries to compile a catalog as complete as possible. However, do primarily upvote answers in languages where the author actually had to put effort into golfing the code.
Catalog
The Stack Snippet at the bottom of this post generates the catalog from the answers a) as a list of shortest solution per language and b) as an overall leaderboard.
To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:
## Language Name, N bytes

where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:
## Ruby, <s>104</s> <s>101</s> 96 bytes

If there you want to include multiple numbers in your header (e.g. because your score is the sum of two files or you want to list interpreter flag penalties separately), make sure that the actual score is the last number in the header:
## Perl, 43 + 2 (-p flag) = 45 bytes

You can also make the language name a link which will then show up in the snippet:
## [><>](http://esolangs.org/wiki/Fish), 121 bytes

 <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b">

Shortest Solution by Language

Language	User	Score

Leaderboard

	Author	Language	Size

{{PLACE}}	{{NAME}}	{{LANGUAGE}}	{{SIZE}}	Link

{{LANGUAGE}}	{{NAME}}	{{SIZE}}	Link

Can I take inputs as negative numbers, where abs(input) would be the number I am testing?

No, the input is a strictly positive integer.

Is there a reason for the full program requirement, rather than allowing the full range of default input types?  E.g. answering with a function that takes its input as an argument, is currently disallowed?
https://codegolf.meta.stackexchange.com/questions/2447/default-for-code-golf-input-output-methods

@LyndonWhite This was intended as a catalog (like “Hello, World!”) of primality tests, so a unified submission format seemed preferable. It's one of two decisions about this challenge that I regret, the other being only allowing deterministic primality tests.

Could a case be made for locking this challenge and posting a new, less restrictive one?

@Shaggy Seems like a question for meta.

Yeah, that's what I was thinking. I'll let you do the honours, seeing as it's your challenge.

Is it ok if an answer falsely says 1 is prime, or would this disqualify and answer?

hello, world!, 13
hello, world!

Did you, like, just create this language, just for this submission? ;)

@ETHproductions Looks like the latest commit was 10 days ago.

@Geobits Ah, my bad, I saw Sep 11 as the date. Still, that's an interesting language you got there. :)

Methinks the program should be hello, worl!, since 0 appears to be the only falsy value in the language. Also, it's shorter. ;)

Also, I don't know if I'm doing something wrong, but my tweaked version on Ideone hangs when given an input of 1.

It's true, if I'd created this language exactly to the spec in the question I'd've done it slightly differently. :p My version suspends judgment on 1 as well.

I was hoping to have the language in slightly better shape before linking to it anywhere, but this challenge was posted and I couldn't resist.

@histocrat The good news is, due to the rules of this particular question, you can update the language and use the new version.

I would almost say that hanging on an input of 1 is correct functionality.

@histocrat It would be cool if your language would get an entry in the hello world challenge http://codegolf.stackexchange.com/questions/55422/hello-world

The best part about this is that the program isn't just a built-in, each character plays its own part in getting the correct result.

How does this work?

@user67719 I guess you could read how on the GitHub repo readme.

egsykhugtyrfv7y 4r7ot 4fv7dfo 434 3f8f <-- my reaction

Hexagony, 29 bytes
.?'.).@@/'/.!.>+=(<.!)}($>(<%

The readable version of this code is:
   . ? ' .
  ) . @ @ /
 ' / . ! . >
+ = ( < . ! )
 } ( $ > ( <
  % . . . .
   . . . .

Explanation: It test if there is a number from 2 to n-1 who divides n.
Initialization:
Write n in one memory cell and n-1 in an other:
   . ? ' .
  . . . . .
 . . . . . .
+ = ( . . . .
 . . . . . .
  . . . . .
   . . . .

Special Case n=1:
Print a 0 and terminate
   . . . .
  . . . @ .
 . . . ! . .
. . . < . . .
 . . . . . .
  . . . . .
   . . . .

The loop
Calculate n%a and decrease a. Terminate if a=1 or n%a=0.
   . . . .
  ) . . . /
 ' / . . . >
. . . . . . .
 } ( $ > ( <
  % . . . .
   . . . .

Case a=1:
Increase a 0 to an 1, print it and terminate. (The instruction pointer runs in NE direction and loops from the eastern corner to the south western corner. And the $ makes sure it ignores the next command)
   . . . .
  . . . @ .
 . . . ! . .
. . . < . . )
 . . $ . . <
  . . . . .
   . . . .

Case a%n=0:
Print the 0 and terminate (The instruction pointer is running SW and loops to the top to the @
   . . . .
  . . @ . .
 . . . . . >
. . . . . ! .
 . . . . . .
  . . . . .
   . . . .

Holy crap, that's one impressive first post. :) I'll put up the bounty right now (I'll award it in 7 days, to draw some more attention to your answer). Welcome to PPCG!

Great answer! +1 for "The readable version of this code is: <...>" :-)

Hexagony, 218 92 58 55 bytes
Notice: This answer has been solidly beaten with a side-length 4 solution by Etoplay.
)}?}.=(..]=}='.}.}~./%*..&.=&{.<......=|>(<..}!=...&@\[

The first ever non-trivial (i.e. non-linear) Hexagony program! It is based on the same squared-factorial approach as Sp3000's Labyrinth answer. After starting out with a hexagon of size 10, I managed to compress it down to size 5. However, I was able to reuse some duplicate code and there are still quite a bunch of no-ops in the code, so size 4 might just be possible.
Explanation
To make sense of the code, we first need to unfold it. Hexagony pads any source code to the next centred hexagonal number with no-ops (.), which is 61. It then rearranges the code into a regular hexagon of the corresponding size:
     ) } ? } .
    = ( . . ] =
   } = ' . } . }
  ~ . / % * . . &
 . = & { . < . . .
  . . . = | > ( <
   . . } ! = . .
    . & @ \ [ .
     . . . . .

This is quite heavily golfed with crossing and overlapping execution paths and multiple instruction pointers (IPs). To explain how it works, let's first look at an ungolfed version where control flow doesn't go through the edges, only one IP is used and the execution paths are as simple as possible:
             . . . . . . . . . . . . .
            . . . . . . . . . . . . . .
           . . . . . . . . . . . . . . .
          . . . . . . . . . . @ . . . . .
         . . . . . . . . . . ! . . . . . .
        . . . . . . . . . . % . . . . . . .
       . . . . . . . . . . ' . . . . . . . .
      . . . . . . . . . . & . . . . . . . . .
     . . . . . . . . . . { . . . . . . . . . .
    . . . . . . . . . . * . . . . . . . . . . .
   . . . . . . . . . . = . . . . . . . . . . . .
  . . . . . . . . . . } . . . . . . . . . . . . .
 ) } ? } = & { < . . & . . . . . . . . . . . . . .
  . . . . . . . > ( < . . . . . . . . . . . . . .
   . . . . . . = . . } . . . . . . . . . . . . .
    . . . . . } . . . = . . . . . . . . . . . .
     . . . . | . . . . | . . . . . . . . . . .
      . . . . * . . . ) . . . . . . . . . . .
       . . . . = . . & . . . . . . . . . . .
        . . . . > } < . . . . . . . . . . .
         . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . .
           . . . . . . . . . . . . . . .
            . . . . . . . . . . . . . .
             . . . . . . . . . . . . .

Side note: the above code starts with executing the first line, which is full of no-ops. Then, when the IP hits the north east edge, it wraps to the left-most corner (the )), where the actual code begins.
Before we start, a word about Hexagony's memory layout. It's a bit like Brainfuck's tape on steroids. In fact, it's not a tape, but it's a hexagonal grid itself (an infinite one), where each edge has an integer value, which is initially 0 (and as opposed to standard Brainfuck, the values are signed arbitrary-precision integers). For this program, we'll be using four edges:

We'll compute the factorial on edge A, count down our input on edge C and store another copy of the input (for the modulo) on edge D. B is used as a temporary edge for computations.
The memory pointer (MP) starts out on edge A and points north (this is important for moving the MP around). Now here is the first bit of the code:
)}?}=&{

) increments edge A to 1 as the basis of the factorial. } makes the MP take a right-turn, i.e. move to edge C (pointing north-east). Here we read the input as an integer with ?. Then we take another right-turn to edge D with }. = reverses the MP, such that it points at the vertex shared with C. & copies the value from C (the input) into D - the value is copied from the left because the current value is non-positive (zero). Finally, we make the MP take a left-turn back to C with {.
Next, < is technically a branch, but we know that the current value is positive, so the IP will always turn right towards the >. A branch hit from the side acts as a mirror, such that the IP moves horizontally again, towards the (, which decrements the value in C.
The next branch, < is actually a branch now. This is how we loop from n-1 down to 1. While the current value in C is positive, the IP takes a right-turn (to execute the loop). Once we hit zero, it will turn left instead.
Let's look at the loop "body". The | are simple mirrors, the > and < are also used as mirrors again. That means the actual loop body boils down to
}=)&}=*}=

} moves the MP to edge B, = reverses its direction to face the vertex ABC. ) increments the value: this is only relevant for the first iteration, where the value of B is still zero: we want to ensure that it's positive, such that the next instruction & copies the right neighbour, i.e. A, i.e. the current value of the factorial computation, into B.
} then moves the MP to A, = reverses it again to face the common vertex. * multiplies both neighbours, i.e. edges B and C and stores the result in A. Finally, we have another }= to return to C, still facing the vertex ABC.
I hope you can see how this computes the factorial of n-1 in A.
So now we've done that, the loop counter in C is zero. We want to square the factorial and then take the modulo with the input. That's what this code does:
&}=*{&'%!@

Since C is zero, & copies the left neighbour, i.e. the factorial in A. }=* moves to B and stores the product of the two copies of the factorial (i.e. the square) in B. { moves back to C, but doesn't reverse the MP. We know that the current value is now positive, so & copies input from D into C. ' the MP backwards to the right, i.e. onto A. Remember, the square of the factorial is in B and the input is in C. So % computes (n-1)!^2 % n, exactly what we're looking for. ! prints the result as an integer (0 or 1) and @ terminates the program.

Okay, but that was the ungolfed version. What about the golfed version? You need to know two more things about Hexagony:

The edges wrap around. If the IP hits an edge of the hexagon, it jumps to the opposite edge. This is ambiguous when the IP hits a corner straight on, so hitting a corner also acts as a branch: if the current value is positive, the IP jumps to the grid edge to its right, otherwise to the one to its left.
There are actually 6 IPs. Each of them starts in a different corner, moving along the edge in the clockwise direction. Only one of them is active at a time, which means you can just ignore the other 5 IPs if you don't want them. You can switch to the next IP (in clockwise order) with ] and to the previous one with [. (You can also choose a specific one with #, but that's for another time.)

There are also a few new commands in it: \ and / are mirrors like |, and ~ multiplies the current value by -1.
So how does the ungolfed version translate to the golfed one? The linear set up code )}?}=&{ and the basic loop structure can be found here:
        ) } ? } .  ->
       . . . . . .
      . . . . . . .
     . . . . . . . .
->  . = & { . < . . .
     . . . . . > ( <
      . . . . . . .
       . . . . . .
        . . . . .

Now the loop body crosses the edges a few times, but most importantly, the actual computation is handed off to the previous IP (which starts at the left corner, moving north east):
        ) . . . .
       = . . . ] .
      } = . . } . .
     ~ . / . * . . .
    . . . . . . . . .
     . . . = . > ( <
      . . } . = . .
       . & . \ [ .
        . . . . .

After bouncing off the branch towards south east, the IP wraps around the edge to the two = in the top left corner (which, together, are a no-op), then bounces off the /. The ~ inverts the sign of the current value, which is important for subsequent iterations. The IP wraps around the same edge again and finally hits [ where control is handed over to the other IP.
This one now executes ~}=)&}=*} which undoes the negation and then just runs the ungolfed loop body (minus the =). Finally it hits ] which hands control back to the original IP. (Note that next time, we execute it this IP, it will start from where it left off, so it will first hit the corner. We need the current value to be negative in order for the IP to jump back to the north west edge instead of the south east one.)
Once the original IP resumes control, it bounces off the \, executes the remaining = and then hits > to feed into the next loop iteration.
Now the really crazy part: what happens when the loop terminates?
        ) . . . .
       . ( . . ] =
      . . ' . } . }
     . . . % * . . &
    . . . . . . . . .
     . . . = | . . <
      . . } ! . . .
       . & @ . . .
        . . . . .

The IP moves north east form the < and wraps around to the north east diagonal. So it ends up on the same execution path as the loop body (&}=*}]). Which is actually pretty cool, because that is exactly the code we want to execute at this point, at least if we add another =} (because }=} is equivalent to {). But how does this not actually enter the earlier loop again? Because ] changes to the next IP which is now the (so far unused) IP which starts in the top right corner, moving south west. From there, the IP continues along the edge, wraps to the top left corner, moves down the diagonal, bounces off the | and terminates at @ while executing the final bit of linear code:
=}&)('%!@

(The )( is a no-op of course - I had to add the ( because the ) was already there.)
Phew... what a mess...

Nice! How new is this? Also, you may wish to create an esolangs page whenever you get a stable release

@mbomb007 I implemented the language two days ago (and designed it over two or three days before that). And yes, I'll definitely add an esolangs page, but I think the spec isn't 100% stable yet (there are still 3 unassigned commands for instance). Once I feel that it's more stable, I'll add it to both esolangs and our meta post.

Under the expanded hex is it wraps to the left-most corner (the 1). What 1 are you talking about there?

@mbomb007 fixed. The ) used to be a 1.

+1 just for the level of detail in your explanation of how it works.  If more languages came with an example that detailed more people could use them :D

Pyth, 4 bytes
}QPQ

Prints True or False.

I know that this is old but now you can also do that like this: P_Q and save 1 byte.

It's now possible with P_

@drobilc You can cut the Q, as an EOF when the function is expecting an argument, it uses the input

If we're adding solutions that now work, /P is an alternate 2 byte option.

Retina, 16 bytes
^(?!(..+)\1+$)..

Try it online!
Let's start with a classic: detecting primes with a regex. Input should be given in unary, using any repeated printable character. The test suite includes a conversion from decimal to unary for convenience.
A Retina program consisting of a single line treats that line as a regex and prints the number of matches found in the input, which will be 0 for composite numbers and 1 for primes.
The lookahead ensures that the input is not composite: backtracking will try every possible substring (of at least 2 characters) for (..+), the lookahead then attempts to match the rest of the input by repeating what was captured here. If this is possible, that means the input has a divisor greater than 1, but which is less than itself. If that is the case the negative lookahead causes the match to fail. For primes there is no such possibility, and the match continues.
The only issue is that this lookahead also accepts 1, so we rule that out by matching at least two characters with ...

That's actually an irregular expression, since the primes do not form a regular language.

@PyRulez Most real-world regex flavours are a lot more powerful than the theoretical concept of regular expressions. I improved the wording though.

The most powerful "regex" engines out in the open right now have recognition power equal to that of a linear bounded automata. Standard issue regex, pattern recursion, unlimited lookhead, and unlimited lookbehind are all you need for context-sensitive parsing (though backreferences and such generally help with complicating efficient parsing), and some have them all. Don't even get me started on the engines that let you embed code into the regex.

HTML+CSS, 254+nmax*28 bytes
We can check primality using regular expressions. Mozilla has @document, which is defined as:
@document [ <url> | url-prefix(<string>) | domain(<string>) | regexp(<string>) ]# {
  <group-rule-body>
}

To filter elements via CSS based on the current URL. This is a single pass, so we have to do two steps:

Get input from the user. This input must somehow be reflected in the current URL.
Reply to the user in as little code as possible.

1. Getting Input
The shortest way I can figure to get input and transfer that to the URL is a GET form with checkboxes. For the regex, we just need some unique string to count appearances.
So we start with this (61 bytes):

1
0
<form method=GET action=#q>

We got two unique
s to indicate whether the entered number is a prime (1) or not (0). We also define the form and it's action.
Followed by nmax checkboxes with the same name (nmax*28 bytes):
<input type=checkbox name=i>

Followed by the submit element (34 bytes):
<input name=d value=d type=submit>

2. Display Answer
We need the CSS (159 bytes) to select the
 to display (1 or 0):
#q,#s,#q:target{display:none}#q:target{display:block}@-moz-document regexp(".*\\?((i=on&)?|(((i=on&)(i=on&)+?)\\4+))d=d#q$"){#s{display:block}#r{display:none}}

» Try it at codepen.io (firefox only)

+1: This is my all time favourite abuse of HTML, and the kind of stuff that makes me love codegolf.

This is certainly interesting, but I'm not sure if it satisfies the rules of this challenge. In particular, I don't think it complies with Your algorithm [...] should, in theory, work for arbitrarily large integers. Couldn't you use a regex on the value of an input field as well?

@Dennis Maybe. Probably even. But that wouldn't solve the problem you mentioned. I leave it here as a non-competing entry, because this is the most on-topic challenge for that.

Why not? If you have a number in unary in an input field, your code would no longer depend on the maximum number.

Hm, I thought about this a bit more, and there's really no difference between having only x checkboxes and an interpreter that has only y-bit numbers. Disregard my previous comment.

A text input taking a string in unary would solve the nmax issue and allow you to count the number of bytes. It would also allow for theoretically arbitrarily high values (based on maximum URL length, which is a browser implementation detail).

Hexagony, 28 bytes
Since Etoplay absolutely trounced  me on this question, I felt that I had to outgolf his only other answer.
?\.">"!*+{&'=<\%(><.*.'(@>'/

Try it online!
I use Wilson's Theorem, like Martin did in his answer: Given n, I output (n-1!)² mod n
Here it the program unfolded:
   ? \ . "
  > " ! * +
 { & ' = < \
% ( > < . * .
 ' ( @ > ' /
  . . . . .
   . . . .

And here is the readable version:

Explanation:
The program has three main steps: Initialisation, Factorial and Output.
Hexagony's memory model is an infinite hexagonal grid. I am using 5 memory locations, as shown in this diagram:

I will be referring to these locations (and the Integers stored in them) by their labels on that diagram.
Initialisation:

The instruction pointer (IP) starts at the top left corner, going East. The memory pointer (MP) starts at IN.
First, ? reads the number from input and stores it in IN. The IP stays on the blue path, reflected by \. The sequence "&( moves the MP back and to the left (to A), copies the value from IN to A and decrements it.
The IP then exits one side of the hexagon and re-enters the other side (onto the green path). It executes '+ which moves the MP to B and copies what was in A. < redirects the IP to West.
Factorial:
I compute the factorial in a specific way, so that squaring it is easy. I store n-1! in both B and C as follows.

The instruction pointer starts on the blue path, heading East.
=' reverses the direction of the MP and moves it backwards to C. This is equivalent to {= but having the = where it is was helpful later.
&{ copies the value from A to C, then moves the MP back to A. The IP then follows the green path, doing nothing, before reaching the red path, hitting \ and going onto the orange path.
With (>, we decrement A and redirect the IP East. Here it hits a branch: <. For positive A, we continue along the orange path. Otherwise the IP gets directed North-East.
'* moves the MP to B and stores A * C in B. This is (n-1)*(n-2) where the initial input was n. The IP then enters back into the initial loop and continues decrementing and multiplying until A reaches 0. (computing n-1!)
N.B: On following loops, & stores the value from B in C, as C has a positive value stored in it now. This is crucial to computing factorial.
Output:

When A reaches 0. The branch directs the IP along the blue path instead.
=* reverses the MP and stores the value of B * C in A. Then the IP exits the hexagon and re-enters on the green path; executing "%. This moves the MP to OUT and calculates A mod IN, or (n-1!)² mod n.
The following {" acts as a no-op, as they cancel each-other out. ! prints the final output and *+'( are executed before termination: @.
After execution, (with an input of 5) the memory looks like this:

The beautiful images of the control flow were made using Timwi's Hexagony Coloror.
Thank you to Martin Ender for generating all of the images, as I couldn't do it on my PC.

What are you using for these memory diagrams? I've seen Esoteric IDE but I couldn't get it to run...

@NieDzejkob you're better off asking Martin in chat , since he made them for me anyway.

@NieDzejkob Yeah, the memory diagram can be exported from the EsoIDE. https://chat.stackexchange.com/rooms/27364/esoteric-programming-languages if you want to chat about this some more.

CJam, 4 bytes
qimp

CJam has a built-in operator for primality testing.

Alternatively: limp

pimp my cjam.

pimp is objectively more pimp

You can also do l~mp

Wait, if CJam has a built in for primality testing, why is it 4 bytes?

@Cyoce, q reads a line of input, i parses it as an integer, and mp is the built-in. CJam has two groups of two-char built-ins: the "extended" ones begin e and the "mathematical"ones  begin m

@flawr I believe (I forgot the source) the Cjam actually means CherryJam, which participated in Google's CodeJam contest.

Help, WarDoq!, 1 byte
P

Outputs 1 if the input is prime, 0 otherwise.

Mornington Crescent, 2448 bytes
We're back in London!
Take Northern Line to Bank
Take Circle Line to Bank
Take District Line to Parsons Green
Take District Line to Bank
Take Circle Line to Hammersmith
Take District Line to Upney
Take District Line to Hammersmith
Take Circle Line to Victoria
Take Victoria Line to Seven Sisters
Take Victoria Line to Victoria
Take Circle Line to Victoria
Take Circle Line to Bank
Take Circle Line to Hammersmith
Take Circle Line to Cannon Street
Take Circle Line to Hammersmith
Take Circle Line to Cannon Street
Take Circle Line to Bank
Take Circle Line to Hammersmith
Take Circle Line to Aldgate
Take Circle Line to Aldgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Aldgate
Take Circle Line to Hammersmith
Take District Line to Upminster
Take District Line to Hammersmith
Take Circle Line to Notting Hill Gate
Take Circle Line to Hammersmith
Take Circle Line to Notting Hill Gate
Take District Line to Upminster
Take District Line to Bank
Take Circle Line to Victoria
Take Circle Line to Temple
Take Circle Line to Aldgate
Take Circle Line to Aldgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Pinner
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Pinner
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Pinner
Take Metropolitan Line to Aldgate
Take Circle Line to Hammersmith
Take District Line to Upminster
Take District Line to Victoria
Take Circle Line to Aldgate
Take Circle Line to Victoria
Take Circle Line to Victoria
Take District Line to Upminster
Take District Line to Embankment
Take Circle Line to Embankment
Take Northern Line to Angel
Take Northern Line to Moorgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Aldgate
Take Circle Line to Aldgate
Take Circle Line to Cannon Street
Take District Line to Upney
Take District Line to Cannon Street
Take District Line to Acton Town
Take District Line to Acton Town
Take Piccadilly Line to Russell Square
Take Piccadilly Line to Hammersmith
Take Piccadilly Line to Russell Square
Take Piccadilly Line to Ruislip
Take Piccadilly Line to Ruislip
Take Metropolitan Line to Preston Road
Take Metropolitan Line to Aldgate
Take Circle Line to Aldgate
Take Circle Line to Cannon Street
Take Circle Line to Aldgate
Take Circle Line to Aldgate
Take Metropolitan Line to Preston Road
Take Metropolitan Line to Moorgate
Take Circle Line to Moorgate
Take Northern Line to Mornington Crescent

Timwi was so kind to implement the control flow stations Temple and Angel in Esoteric IDE as well as add input and integer parsing to the language specification.
This one is probably better golfed than the "Hello, World!", because this time I wrote a CJam script to help me find the shortest path between any two stations. If you want to use it (although I don't know why anyone would want to...), you can use the online interpreter. Paste this code:
"Mornington Crescent"
"Cannon Street"
]qN/{'[/0=,}$:Q;{Q{1$#!}=\;_oNo'[/1>{']/0="[]"\*}%}%:R;NoQ{R\f{f{\#)}:+}:*},N*

Here the first two lines are the stations you want to check. Also, paste the contents of this pastebin into the input window.
The output will show you which lines are available at the two stations, and then a list of all stations which connect the two, sorted by the length of the station names. It shows all of them, because sometimes it's better to use a longer name, either because it allows a shorter line, or because the station is special (like Bank or Temple) so that you want to avoid it. There are some edge cases where two stations aren't connected by any single other station (notably, the Metropolitan and District lines never cross), in which case you'll have to figure out something else. ;)
As for the actual MC code, it's based on the squared-factorial approach as many other answers because MC has multiplication, division and modulo. Also, I figured that a single loop would be convenient.
One issue is that the loops are do-while loops, and decrementing and incrementing is expensive, so I can't easily compute (n-1)! (for n > 0). Instead, I'm computing n! and then divide by n at the end. I'm sure there is a better solution for this.
When I started writing this, I figured that storing -1 in Hammersmith would be a good idea so I can decrement more cheaply, but in the end this may have cost more than it saved. If I find the patience to redo this, I might try just keeping a -1 around in Upminster instead so I can use Hammersmith for something more useful.

Is London turing complete?

@RohanJhunjhunwala probably

Wow! I love seeing well thought out questions. I especially love seeing questions where you have to write a program to write a program.

Minor question - how did you store -1 in Hammersmith? I'm thinking of doing the same for a program I'm writing. I'm guessing it was by Notting Hill Gate, but I could be wrong.

@Cloudy7 Yeah something like that. I just stepped through the program in the Esoteric IDE, and apparently I picked up the 7 from Seven Sisters, divided by itself in Chalfont & Latimer to get a 1, negated in Notting Hill Gate to get a -2 and added those together in Upminster for a -1. In hindsight, this seems a little unnecessarily complicated. I think I could've just done the last two steps to the input (without picking up the 7, or dividing by itself).

@MartinEnder Wow, that's still better than what I dreamed up, which was getting the name of the station "Bromley-by-Bow", getting the last seven characters at Mile End, using Charing Cross twice to get the hyphen out, then concatenating with a string containing a number at Paddington. (Interestingly, Notting Hill Gate seems to add 1 to any positive integer and then negate it. Weird.)

@Cloudy7 Yeah, you're right, I meant Cannon Street.

@MartinEnder I just realized, looking at this a year later, that a significant number of bytes could be shaved off here, as you can obtain the value -1 by parsing a string without a number in it at Parsons Green to obtain 0, then using Notting Hill Gate to turn it to -1. This would remove the need to use Cannon Street entirely. Also, there are a couple station names that could be reduced -- "Embankment" can be replaced with "Bank", for instance.

Brachylog (V2), 1 byte
ṗ

Try it online!
Brachylog (V1), 2 bytes
#p
This uses the built-in predicate #p - Prime, which constrains its input to be a prime number.
Brachylog is my attempt at making a Code Golf version of Prolog, that is a declarative code golf language that uses backtracking and unification.
Alternate solution with no built-in: 14 bytes
ybbrb'(e:?r%0)

Here is a breakdown of the code above:
y            The list [0, …, Input]
bbrb         The list [2, …, Input - 1]
'(           True if what's in the parentheses cannot be proven; else false
     e           Take an element from the list [2, …, Input - 1]
     :?r%0       The remainder of the division of the Input but that element is 0
)

You might want to edit the Brachylog 2 version of this into the post, too, now that the syntax is a byte shorter.

@ais523 True, done.

Does the Brachylog 2 answer postdate the challenge?

@ScottMilner Yes, but this is explicitely allowed in this challenge: "Unlike our usual rules, feel free to use a language (or language version) even if it's newer than this challenge"

Haskell, 49 bytes
Using xnor's Corollary to Wilson's Theorem:
main=do n<-readLn;print$mod(product[1..n-1]^2)n>0

Wouldn't it be shorter to do main=interact$\n-> ...?

Counterintuitively, no! Consider that you'd need interact...read in there somewhere, which makes it a lot longer than just readLn. Often do notation can be more concise than you might expect, especially when the alternative is a lambda.

Labyrinth, 29 bytes
1
?
:
}  +{%!@
(:'(
 } {
 :**

Reads an integer from STDIN and outputs ((n-1)!)^2 mod n. Wilson's theorem is pretty useful for this challenge.
The program starts at the top-left corner, beginning with 1 which multiplies the top of the stack by 10 and adds 1. This is Labyrinth's way of building large numbers, but since Labyrinth's stacks are filled with zeroes, the end effect is as though we just pushed a 1.
? then reads n from STDIN and : duplicates it. } shifts n to the auxiliary stack, to be used at the end for the modulo. ( then decrements n, and we are ready to begin calculating the squared factorial.
Our second : (duplicate) is at a junction, and here Labyrinth's control flow features come into play. At a junction after an instruction is executed, if the top of the stack is positive we turn right, for negative we turn left and for zero we go straight ahead. If you try to turn but hit a wall, Labyrinth makes you turn in the other direction instead.
For n = 1, since the top of the stack is n decremented, or 0, we go straight ahead. We then hit a no-op ' followed by another decrement ( which puts us at -1. This is negative, so we turn left, executing + plus  (-1 + 0 = -1), { to shift n back from the auxiliary stack to the main and % modulo (-1 % 1 = 0). Then we output with ! and terminate with @.
For n > 1, at the second : we turn right. We then shift } our copied loop counter to the auxiliary stack, duplicate : and multiply twice **, before shifting the counter back { and decrementing (. If we're still positive we try to turn right but can't, so Labyrinth makes us turn left instead, continuing the loop. Otherwise, the top of the stack is our loop counter which has been reduced to 0, which we + add to our calculated ((n-1)!)^2. Finally, we shift n back with { then modulo %, output ! and terminate @.
I said that ' is a no-op, but it can also be used for debugging. Run with the -d flag to see the state of the stack every time the ' is passed over!

Squaring the factorial is a really cool trick :)

@Mauris Thanks! I need to give credit where it is due though - I first saw the trick used by xnor here

Yay, the first Labyrinth answer not written by me! :)

Bash + GNU utilities, 16

4 bytes saved thanks to @Dennis

2 bytes saved thanks to @Lekensteyn

factor|awk NF==2

Input is one line taken from STDIN.  Output is empty string for falsey and non-empty string for truthy. E.g.:
$ ./pr.sh <<< 1
$ ./pr.sh <<< 2
2: 2
$ ./pr.sh <<< 3
3: 3
$ ./pr.sh <<< 4
$

Cool, learned about another coreutil. Your can strip two characters by counting the number of fields: factor|awk NF==2

@Lekensteyn - thanks - for some reason I missed your comment before :)

I was going to post something somewhat similar, only longer and without AWK. Nicely done.

Java, 126 121 bytes
I guess we need a Java answer for the scoreboard... so here's a simple trial division loop:
class P{public static void main(String[]a){int i=2,n=Short.valueOf(a[0]);for(;i<n;)n=n%i++<1?0:n;System.out.print(n>1);}}

As usual for Java, the "full program" requirement makes this much larger than it would be if it were a function, due mostly to the main signature.
In expanded form:
class P{
    public static void main(String[]a){
        int i=2,n=Short.valueOf(a[0]);
        for(;i<n;)
            n=n%i++<1?0:n;
        System.out.print(n>1);
    }
}

Edit: Fixed and regolfed by Peter in comments. Thanks!

Buggy: it reports that 1 is prime. Otherwise there'd be a 4-char saving by removing p and saying for(;i<n;)n=n%i++<1?0:n;System.out.print(n>0);

OTOH class P{public static void main(String[]a){int i=2,n=Short.valueOf(a[0]);for(;i<n;)n=n%i++<1?0:n;System.out.print(n>1);}} works

changing line 3 to 'long i=2,n=Long.valueOf(a[0]);` results in no change in length but a wider range of valid inputs.

Instead of .valueOf you can use new, as in new Short(a[0]), or new Long(a[0]), which is a bit shorter.

You can save 4 bytes by using an interface and dropping the public modifier.

JavaScript, 39 36 bytes
Saved 3 bytes thanks to ETHproductions:
for(i=n=prompt();n%--i;);alert(1==i)

Displays true for a prime, false otherwise.
The for loop tests every number i from n-1 until i is a divisor.
If the first divisor found is 1 then it's a prime number.

Previous solution (39 bytes):
for(i=n=prompt();n%--i&&i;);alert(1==i)

How was left an unneeded test:
for(i=2,n=prompt();n%i>0&&i*i<n;i++);alert(n%i>0) //49: Simple implementation: loop from 2 to sqrt(n) to test the modulo.
for(i=2,n=prompt();n%i>0&&i<n;i++);alert(n==i)    //46: Replace i*i<n by i<n (loop from 2 to n) and replace n%i>0 by n==i
for(i=2,n=prompt();n%i&&i<n;i++);alert(n==i)      //44: Replace n%i>0 by n%i
for(i=2,n=prompt();n%i&&i++<n;);alert(n==i)       //43: Shorten loop increment
for(i=n=prompt();n%--i&&i>0;);alert(1==i)         //41: Loop from n to 1. Better variable initialization.
for(i=n=prompt();n%--i&&i;);alert(1==i)           //39: \o/ Replace i>0 by i

I only posted the 39 bytes solution because the best JavaScript answer was already 40 bytes.

Welcome to Programming Puzzles & Code Golf!

Great answer! The &&i doesn't actually do anything in this program, so you can remove it.

should add n>1 to the final condition though, if You don´t want 1 to be prime.

@Titus If the input is 1 the for loop will do n%--i once : 1%0 returns NaN and stops the loop. When alert is called i is already equal to 0 so 1==i returns false.

i<2 (and some text)

f=n=>/666/.test(d=n)&eval("for(;n%--d;)d<3")?n:f(n-1)

R, 37 29 bytes
n=scan();cat(sum(!n%%1:n)==2)

Uses trial division. scan() reads an integer from STDIN and cat() writes to STDOUT.
We generate a vector of length n consisting of the integers 1 to n modulo n. We test whether each is 0 by negating (!), which returns a logical value that's true when the number is 0 and false when it's greater than 0. The sum of a logical vector is the number of true elements, and for prime numbers we expect the only nonzero moduli to be 1 and n, thus we expect the sum to be 2.
Saved 8 bytes thanks to flodel!

With f=function(x)sum(!x%%1:x)==2 you can do it in 28 bytes.

@AndréMuta For this challenge, all submissions must be full programs rather than just functions. Thanks for the suggestion though.

Stack Cats, 62 + 4 = 66 bytes
*(>:^]*(*>{<-!<:^>[:((-<)<(<!-)>>-_)_<<]>:]<]]}*<)]*(:)*=<*)>]

Needs to be run with the -ln command-line flags (hence +4 bytes). Prints 0 for composite numbers and 1 for primes.
Try it online!
I think this is the first non-trivial Stack Cats program.
Explanation
A quick Stack Cats introduction:

Stack Cats operates on an infinite tape of stacks, with a tape head pointing at a current stack. Every stack is initially filled with an infinite amount of zeros. I will generally ignore these zeros in my wording, so when I say "the bottom of stack" I mean the lowest non-zero value and if I say "the stack is empty" I mean there's only zeros on it.
Before the program starts, a -1 is pushed onto the initial stack, and then the entire input is pushed on top of that. In this case, due to the -n flag, the input is read as a decimal integer.
At the end of the program, the current stack is used for output. If there's a -1 at the bottom, it will be ignored. Again, due to the -n flag, the values from the stack are simply printed as linefeed-separated decimal integers.
Stack Cats is a reversible program language: every piece of code can be undone (without Stack Cats keeping track of an explicit history). More specifically, to reverse any piece of code, you simply mirror it, e.g. <<(\-_) becomes (_-/)>>. This design goal places fairly severe restrictions on what kinds of operators and control flow constructs exist in the language, and what sorts of functions you can compute on the global memory state.
To top it all off, every Stack Cats program has to be self-symmetric. You might notice that this is not the case for the above source code. This is what the -l flag is for: it implicitly mirrors the code to the left, using the first character for the centre. Hence the actual program is:
[<(*>=*(:)*[(>*{[[>[:<[>>_(_-<<(-!>)>(>-)):]<^:>!->}<*)*[^:<)*(>:^]*(*>{<-!<:^>[:((-<)<(<!-)>>-_)_<<]>:]<]]}*<)]*(:)*=<*)>]

Programming effectively with the entire code is highly non-trivial and unintuitive and haven't really figured out yet how a human can possibly do it. We've brute forced such program for simpler tasks, but wouldn't have been able to get anywhere near that by hand. Luckily, we've found a basic pattern which allows you to ignore one half of the program. While this is certainly suboptimal, it's currently the only known way to program effectively in Stack Cats.
So in this answer, the template of said pattern is this (there's some variability in how it's executed):
[<(...)*(...)>]

When the program starts, the stack tape looks like this (for input 4, say):
     4
... -1 ...
     0
     ^

The [ moves the top of the stack to the left (and the tape head along) - we call this "pushing". And the < moves the tape head alone. So after the first two commands, we've got this situation:
...   4 -1 ...
    0 0  0
    ^

Now the (...) is a loop which can be used quite easily as a conditional: the loop is entered and left only when the top of the current stack is positive. Since, it's currently zero, we skip the entire first half of the program. Now the centre command is *. This is simply XOR 1, i.e. it toggles the least significant bit of the top of the stack, and in this case turns the 0 into a 1:
... 1 4 -1 ...
    0 0  0
    ^

Now we encounter the mirror image of the (...). This time the top of the stack is positive and we do enter the code. Before we look into what goes on inside the parentheses, let me explain how we'll wrap up at the end: we want to ensure that at the end of this block, we have the tape head on a positive value again (so that the loop terminates after a single iteration and is used simply as a linear conditional), that the stack to the right holds the output and that the stack right of that holds a -1. If that's the case, we do leave the loop, > moves onto the output value and ] pushes it onto the -1 so we have a clean stack for output.
That's that. Now inside the parentheses we can do whatever we want to check the primality as long as we ensure that we set things up as described in the previous paragraph at the end (which can easily done with some pushing and tape head moving). I first tried solving the problem with Wilson's theorem but ended up well over 100 bytes, because the squared factorial computation is actually quite expensive in Stack Cats (at least I haven't found a short way). So I went with trial division instead and that indeed turned out much simpler. Let's look at the first linear bit:
>:^]

You've already seen two of those commands. In addition, : swaps the top two values of the current stack and ^ XORs the second value into the top value. This makes :^ a common pattern to duplicate a value on an empty stack (we pull a zero on top of the value and then turn the zero into 0 XOR x = x). So after this, section our tape looks like this:
         4
... 1 4 -1 ...
    0 0  0
         ^

The trial division algorithm I've implemented doesn't work for input 1, so we should skip the code in that case. We can easily map 1 to 0 and everything else to positive values with *, so here's how we do that:
*(*...)

That is we turn 1 into 0, skip a big part of the code if we get indeed 0, but inside we immediately undo the * so that we get our input value back. We just need to make sure again that we end on a positive value at the end of the parentheses so that they don't start looping. Inside the conditional, we move one stack right with the > and then start the main trial division loop:
{<-!<:^>[:((-<)<(<!-)>>-_)_<<]>:]<]]}

Braces (as opposed to parentheses) define a different kind of loop: it's a do-while loop, meaning it always runs for at least one iteration. The other difference is the termination condition: when entering the loop Stack Cat remembers the top value of the current stack (0 in our case). The loop will then run until this same value is seen again at the end of an iteration. This is convenient for us: in each iteration we simply compute the remainder of the next potential divisor and move it onto this stack we're starting the loop on. When we find a divisor, the remainder is 0 and the loop stops. We will try divisors starting at n-1 and then decrement them down to 1. That means a) we know this will terminate when we reach 1 at the latest and b) we can then determine whether the number is prime or not by inspecting the last divisor we tried (if it's 1, it's a prime, otherwise it isn't).
Let's get to it. There's a short linear section at the beginning:
<-!<:^>[:

You know what most of those things do by now. The new commands are - and !. Stack Cats does not have increment or decrement operators. However it has - (negation, i.e. multiply by -1) and ! (bitwise NOT, i.e. multiply by -1 and decrement). These can be combined into either an increment, !-, or decrement -!. So we decrement the copy of n on top of the -1, then make another copy of n on the stack to the left, then fetch the new trial divisor and put it beneath n. So on the first iteration, we get this:
      4
      3
... 1 4 -1 ...
    0 0  0
      ^

On further iterations, the 3 will replaced with the next test divisor and so on (whereas the two copies of n will always be the same value at this point).
((-<)<(<!-)>>-_)

This is the modulo computation. Since loops terminate on positive values, the idea is to start from -n and repeatedly add the trial divisor d to it until we get a positive value. Once we do, we subtract the result from d and this gives us the remainder. The tricky bit here is that we can't just have put a -n on top of the stack and start a loop that adds d: if the top of the stack is negative, the loop won't be entered. Such are the limitations of a reversible programming language.
So to circumvent this issue, we do start with n on top of the stack, but negate it only on the first iteration. Again, that sounds simpler than it turns out to be...
(-<)

When the top of the stack is positive (i.e. only on the first iteration), we negate it with -. However, we can't just do (-) because then we wouldn't be leaving the loop until - was applied twice. So we move one cell left with < because we know there's a positive value there (the 1). Okay, so now we've reliably negated n on the first iteration. But we have a new problem: the tape head is now in a different position on the first iteration than in every other one. We need to consolidate this before we move on. The next < moves the tape head left. The situation on the first iteration:
        -4
         3
...   1  4 -1 ...
    0 0  0  0
    ^

And on the second iteration (remember we've added d once into -n now):
      -1
       3
... 1  4 -1 ...
    0  0  0
    ^

The next conditional merges these paths again:
(<!-)

On the first iteration the tape head points at a zero, so this is skipped entirely. On further iterations, the tape head points at a one though, so we do execute this, move to the left and increment the cell there. Since we know the cell starts from zero, it will now always be positive so we can leave the loop. This ensures we always end up two stack left of the main stack and can now move back with >>. Then at the end of the modulo loop we do -_. You already know -. _ is to subtraction what ^ is to XOR: if the top of the stack is a and the value underneath is b it replaces a with b-a. Since we first negated a though, -_ replaces a with b+a, thereby adding d into our running total.
After the loop ends (we've reached a positive) value, the tape looks like this:
        2
        3
... 1 1 4 -1 ...
    0 0 0  0
        ^

The left-most value could be any positive number. In fact, it's the number of iterations minus one. There's another short linear bit now:
_<<]>:]<]]

Like I said earlier we need to subtract the result from d to obtain the actual remainder (3-2 = 1 = 4 % 3), so we just do _ once more. Next, we need to clean up the stack that we've been incrementing on the left: when we try the next divisor, it needs to be zero again, for the first iteration to work. So we move there and push that positive value onto the other helper stack with <<] and then move back onto our operational stack with another >. We pull up d with : and push it back onto the -1 with ] and then we move the remainder onto our conditional stack with <]]. That's the end of the trial division loop: this continues until we get a zero remainder, in which case the stack to the left contains n's greatest divisor (other than n).
After the loop ends, there's just *< before we join paths with the input 1 again. The * simply turns the zero into a 1, which we'll need in a bit, and then we move to the divisor with < (so that we're on the same stack as for input 1).
At this point it helps to compare three different kinds of inputs. First, the special case n = 1 where we haven't done any of that trial division stuff:
         0
... 1 1 -1 ...
    0 0  0
         ^

Then, our previous example n = 4, a composite number:
    2
    1    2 1
... 1 4 -1 1 ...
    0 0  0 0
         ^

And finally, n = 3, a prime number:
    3
    1    1 1
... 1 3 -1 1 ...
    0 0  0 0
         ^

So for prime numbers, we have a 1 on this stack, and for composite numbers we either have a 0 or a positive number greater than 2. We turn this situation into the 0 or 1 we need with the following final piece of code:
]*(:)*=<*

] just pushes this value to the right. Then * is used to simplify the conditional situation greatly: by toggling the least significant bit, we turn 1 (prime) into 0, 0 (composite) into the positive value 1, and all other positive values will still remain positive. Now we just need to distinguish between 0 and positive. That's where we use another (:). If the top of the stack is 0 (and the input was a prime), this is simply skipped. But if the top of the stack is positive (and the input was a composite number) this swaps it with the 1, so that we now have 0 for composite and 1 for primes - only two distinct values. Of course, they are the opposite of what we want to output, but that is easily fixed with another *.
Now all that's left is to restore the pattern of stacks expected by our surrounding framework: tape head on a positive value, result on top of the stack to the right, and a single -1 on the stack right of that. This is what =<* is for. = swaps the tops of the two adjacent stacks, thereby moving the -1 to the right of the result, e.g. for input 4 again:
    2     0
    1     3
... 1 4   1 -1 ...
    0 0 0 0  0
          ^

Then we just move left with < and turn that zero into a one with *. And that's that.
If you want to dig deeper into how the program works, you can make use of the debug options. Either add the -d flag and insert " wherever you want to see the current memory state, e.g. like this, or use the -D flag to get a complete trace of the entire program. Alternatively, you can use Timwi's EsotericIDE which includes a Stack Cats interpreter with a step-by-step debugger.

>:^] should be the official Stack Cats logo

Brain-Flak, 112 108 bytes
({}[()]){((({})())<>){{}<>(({}<(({}[()])()<>)>)<>)<>{({}[()]<({}[()]<({}())>)>{(<()>)}{})}{}{}}}<>{{}}([]{})

Try it online!
How it works
Initially, the first stack will contain a positive integer n, the second stack will be empty.
We start by decrementing n as follows.
(
  {}      Pop n.
  [()]    Yield -1.
)       Push n - 1.

n = 1
If n = 1 is zero, the while loop
{
  ((({})())<>)
  {
    {}<>(({}<(({}[()])()<>)>)<>)<>{({}[()]<({}[()]<({}())>)>{(<()>)}{})}{}{}
  }
}

is skipped entirely. Finally, the remaining code is executed.
<>    Switch to the second stack (empty).
{}    Pop one of the infinite zeroes at the bottom.
{<>}  Switch stacks while the top on the active stack is non-zero. Does nothing.
(
  []    Get the length of the active stack (0).
  {}    Pop another zero.
)     Push 0 + 0 = 0.

n > 1
If n - 1 is non-zero, we enter the loop that n = 1 skips. It isn't a "real" loop; the code is only executed once. It achieves the following.
{                   While the top of the active stack is non-zero:
  (
    (
      ({})                Pop and push n - 1.
      ()                  Yield 1.
    )                   Push n - 1 + 1 = n.
    <>                  Switch to the second stack. Yields 0.
  )                   Push n + 0 = n.
                      We now have n and k = n - 1 on the first stack, and n on
                      the second one. The setup stage is complete and we start
                      employing trial division to determine n's primality.
  {                   While the top of the second stack is non-zero:
    {}                  Pop n (first run) or the last modulus (subsequent runs),
                        leaving the second stack empty.
    <>                  Switch to the first stack.
    (
      (
        {}                  Pop n from the first stack.
        <
          (
            (
              {}              Pop k (initially n - 1) from the first stack.
              [()]            Yield -1.
            )               Push k - 1 to the first stack.
            ()              Yield 1.
            <>              Switch to the second stack.
          )               Push k - 1 + 1 = k on the second stack.
        >               Yield 0.
      )               Push n + 0 = n on the second stack.
      <>              Switch to the first stack.
    )               Push n on the first stack.
    <>              Switch to the second stack, which contains n and k.
                    The first stack contains n and k - 1, so it is ready for
                    the next iteration.
    {({}[()]<({}[()]<({}())>)>{(<()>)}{})}{}{}  Compute and push n % k.
  }               Stop if n % k = 0.
}               Ditto.

n % k is computed using the 42-byte modulus algorithm from my divisibility test answer.
Finally, we interpret the results to determine n's primality.
<>    Switch to the first stack, which contains n and k - 1, where k is the
      largest integer that is smaller than n and divides n evenly.
      If (and only if) n > 1 is prime, k = 1 and (thus) k - 1 = 0.
{     While the top of the first stack is non-zero:
  {}    Pop it.
}     This pops n if n is prime, n and k - 1 if n is composite.
(
  []    Yield the height h of the stack. h = 1 iff n is prime).
  {}    Pop 0.
)     Push h + 0 = h.

You don't need to pop the last 0 on the stack, since the truthy 1 on top is enough; you can save two bytes that way by removing the last {}.

Hm, I'm torn. On one hand, the question says that output should consist solely of a truthy or falsy value and 1 0 is two values. On the other hand, we'd accept arrays as long as the language considers them truthy or falsy and multiple stack items is the closest thing Brain-Flak has to arrays. Might be worth taking this to meta.

I've verified with the creator of Brain-Flak that 1 0 is truthy. http://chat.stackexchange.com/transcript/message/32746241#32746241

Relevant meta discussion: Truthiness in Brain-Flak and similar stack-based languages

TI-BASIC, 12 bytes
2=sum(not(fPart(Ans/randIntNoRep(1,Ans

Pretty straightforward. randIntNoRep( gives a random permutation of all integers from 1 to Ans.
This bends the rules a little; because lists in TI-BASIC are limited to 999 elements I interpreted

assume that the input can be stored in your data type

as meaning that all datatypes can be assumed to accommodate the input. OP agrees with this interpretation.
A 17-byte solution which actually works up to 10^12 or so:
2=Σ(not(fPart(Ans/A)),A,1,Ans

@toothbrush TI-BASIC is a tokenized language, so every token here is one byte, except for randIntNoRep( which is two.

+1 Ah, I've never seen TL-BASIC before. Thanks for letting me know

Although, it is a bit unfair, isn't it...? I should write a golfing language that requires only 1-4 bytes (the question ID), and then the parameters. It will pick the top answer in a language it understands, execute it (passing any parameters), and return the result... I wonder if that's breaking the rules? :-)

@toothbrush In TI-BASIC's defense: to the interpreter, it's no more unfair than Pyth and CJam's one-character commands, and TI-BASIC is more readable.

True. I dislike those kinds of languages, since solutions in almost every other language are longer... although I recently beat CJam with VB6! :-]

@toothbrush that would most definitely break the rule about using resources created after the start of a challenge. --Note that athough they are overall best, many languages have beaten CJam/Pyth.

I should probably upgrade my OS just to get access to new commands like the one you used in the second solution. Well done. +1

@Toothbrush, that would be breaking the rules, bigtime. You might be able to get away with it if you give the submissions WITH the language, rather than accessing the internet.

@Zacharý Yes, it was a joke. The comment is almost 2 years old now, too.

@Zacharý And when I posted that comment – to the best of my knowledge – such a thing wasn't forbidden by any rule.

TI-BASIC, 24 bytes
Note that TI-Basic programs use a token system, so counting characters does not return the actual byte value of the program.
Upvote Thomas Kwa's answer, it is superior.
:Prompt N
:2
:While N≠1 and fPart(N/Ans
:Ans+1
:End
:N=Ans

Sample:
N=?1009
                         1
N=?17
                         1
N=?1008
                         0
N=?16
                         0

Now returns 0 if not a prime, or 1 if it is.

Isn't the square root just an optimisation that you don't actually need for the program to be correct?

Why would you need to divide by two?

I always love TI-BASIC answers.

Why choose Prompt over Input? They're the same number of bytes, and when it's a single variable Input would be more idomatic...

@HelloGoodbye Because the UI is better for free, if I recall my reasoning correctly.

Ok, seems legit

C++ template metaprogramming.  166 131 119 bytes.
Code compiles if the constant is a prime, and does not compile if composite or 1.
template<int a,int b=a>struct t{enum{x=t::x+!(a%b)};};
template<int b>struct t{enum{x};};
int _[t<1>::x==2];

(all newlines, except final one, are eliminated in "real" version).
I figure "failure to compile" is a falsey return value for a metaprogramming language.  Note that it does not link (so if you feed it a prime, you'll get linking errors) as a full C++ program.
The value to test is the integer on the last "line".
live example.

Ruby, 15 + 8 = 23 bytes
p$_.to_i.prime?

Sample run:
bash-4.3$ ruby -rprime -ne 'p$_.to_i.prime?' <<< 2015
false

Heheh, I knew there would be a builtin in Ruby somewhere, but I couldn't be bothered to look for it, so I answered in C. +1.

@steveverrill, I knew it because was a big help for Project Euler.

Python 3, 59 bytes
Now uses input() instead of command line arguments. Thanks to @Beta Decay
n=int(input())
print([i for i in range(1,n)if n%i==0]==[1])

Take input using input() would be much shorter

Thanks, I've already written with using of input(), but I forgot to refresh my answer. Thanks again!

52 bytes: n=m=int(input()), print(all(n%m for m in range(2,n)))

for i in range(2,math.sqrt(n)+1)

Are you serious. Spend 25 extra characters for a lame quadratic speedup? Here we hate bytes. We spend every hour,minute, and second of our lives getting rid of the nineteenth byte. (Just kidding. But we don't do time optimizations that increase program length.)

Use n%i<1 instead.

Outgolfed! Mine uses a completely different method. Rather than n%i==0, though, you could have n%i<1 because stuff using mod is never negative. That would save a byte.

If you used Python 2, you could change int(input()) to input() because of Python 2's eval. However, using a lambda would be even shorter

50 chars, n=int(input());print(all(n%m for m in range(2,n)))

@TheMatt - Doesn't work for 1 though. 1 isn't prime but this says it is.

@SwimBikeRun, you're correct. Mine is only an improvement on John Lyon though it doesn't meet requirements for n < 2. Sorry for the confusion.

Ah I see, I figured this out after reading the original post more closely. Thanks!

replace n%i==0 by n%i<1

PARI/GP, 21 bytes
print(isprime(input))

Works for ridiculously big inputs, because this kind of thing is what PARI/GP is made for.

isprime does an APR-CL primality proof, so does slow down quite a bit as inputs get very large.  ispseudoprime(input) does an AES BPSW probable prime test, which will be much faster for over 100 digits.  Still no known counterexamples after 35 years.   Version 2.1 and earlier of Pari, from pre-2002, uses a different method that can easily give false results, but nobody should be using that.

Why not i->isprime(i) or just isprime, that's shorter?

@JeppeStigNielsen The challenge says: “Write a full program that …”

OK, that might be the correct interpretation, if you insist on reading with input() and writing with print(...). However, I thought a function like foo(x, y) = { z=bar(x); if(y, return(y*z)); z } or something was a "full program" in PARI/GP. It is not usual to do input() and print(...), more common to use return values (functional language).

C, 67 bytes
i,n;main(p){for(scanf("%d",&i),n=i;--i;p=p*i*i%n);putchar(48+p%n);}

Prints !1 (a falsey value, by Peter Taylor's definition) 0 if (n-1)!^2 == 0 (mod n), and 1 otherwise.
EDIT: After some discussion in chat, puts("!1"+p%n) seems to be considered a bit cheaty, so I've replaced it. The result is one byte longer.
EDIT: Fixed for big inputs.
Shorter solutions
56 bytes: As recommended in the comments by pawel.boczarski, I could take input in unary by reading the number of command line arguments:
p=1,n;main(i){for(n=--i;--i;p=p*i*i%n);putchar(48+p%n);}

invoking the program like
$ ./a.out 1 1 1 1 1
1                        <-- as 5 is prime

51 bytes: If you allow "output" by means of return codes:
p=1,n;main(i){for(n=--i;--i;p=p*i*i%n);return p%n;}

Your solution could be made shorter using unary representation (number of commandline arguments), as in my solution posted. You could shave off some bytes on scanf call.

puts("!1"+p%n) How could you ever do a+b for char* values?

If the string "!1" starts at address a, then at a+1 you’ll find the string "1".

@Lynn Oh, I thought it was for concatenation (yeah, better leave that to strcat(const char*,const char*).)

Could you change p=p*i*i%n to p*=i*i%n

I may be wrong, but can't you use 48+p instead of 48+p%n? The only time you assign to p is in the statement p=p*i*i%n, so p will always be less than n.

Haskell, 54 bytes
import Data.Numbers.Primes
main=readLn>>=print.isPrime

Nothing much to explain.

The same score can be achieved (although very inefficiently) without external libraries, using Wilson's theorem: main=do n<-readLn;print$n>1&&mod(product[1..n-1]+1)n<1

We can even do shorter: main=do n<-readLn;print$mod(product[1..n-1]^2)n>0 is 49 bytes.

@Mauris: Nice. Please post it as a separate answer.

Python 2, 44
P=n=1
exec"P*=n*n;n+=1;"*~-input()
print P%n

Like Sp3000's Python answer, but avoids storing the input by counting the variable n up from 1 to the input value.

APL, 40 13 bytes
2=+/0=x|⍨⍳x←⎕

Trial division with the same algorithm as my R answer. We assign x to the input from STDIN (⎕) and get the remainder for x divided by each integer from 1 to x. Each remainder is compared against 0, which gives us a vector of ones and zeros indicating which integers divide x. This is summed using +/ to get the number of divisors. If this number is exactly 2, this means the only divisors are 1 and x, and thus x is prime.

I think two bytes could be shaved off by calculating the greatest common denominator of x with 1...x (x∨⍳x) instead of the residue, then checking how many are unique (+/≠), and comparing that to 2: 2=+/≠x∨⍳x←⎕

Snails, 122
Input should be given in unary. The digits may be any mix of characters except newlines.
^
..~|!(.2+~).!~!{{t.l=.r=.}+!{t.!.!~!{{r!~u~`+(d!~!.r~)+d~,.r.=.(l!~u~)+(d!~l~)+d~,.l.},l=(.!.)(r!~u~)+(d!~!.r~)+d~,.r.!.

In this 2D pattern matching language, the program state consists solely of the current grid location, the set of cells which have been matched, and the position in the pattern code. It's also illegal to travel onto a matched square. It's tricky, but possible to store and retrieve information. The restriction against traveling onto a matched cell can be overcome by backtracking, teleporting (t) and assertions (=, !) which leave the grid unmodified after completing.

The factorization for an odd composite number begins by marking out some set of mutually non-adjacent cells (blue in diagram). Then, from each yellow cell, the program verifies that there are an equal number of non-blue cells on either side of the adjacent blue one by shuttling back and forth between the two sides. The diagram shows this pattern for one of the four yellow cells which must be checked.
Annotated code:
^                         Match only at the first character
..~ |                     Special case to return true for n=2
!(.2 + ~)                 Fail for even numbers
. !~                      Match 1st character and fail for n=1
!{                        If the bracketed pattern matches, it's composite.
  (t. l=. r=. =(.,~) )+   Teleport to 1 or more chars and match them (blue in graphic)
                          Only teleport to ones that have an unmatched char on each side.
                          The =(.,~) is removed in the golfed code. It forces the
                          teleports to proceed from left to right, reducing the
                          time from factorial to exponential.
  !{                      If bracketed pattern matches, factorization has failed.
    t . !. !~             Teleport to a square to the left of a blue square (yellow in diagram)
    !{                    Bracketed pattern verifies equal number of spaces to
                          the left or right of a blue square.
      {
        (r!~ u~)+         Up...
        (d!~!. r~)+       Right...
        d~,               Down...
        . r . =.          Move 1 to the right, and check that we are not on the edge;
                          otherwise d~, can fall off next iteration and create and infinite loop
        (l!~ u~)+         Up...
        (d!~ l~)+         Left...
        d ~,              Down...
        . l .             Left 1
      } ,                 Repeat 0 or more times
      l  =(. !.)          Check for exactly 1 unused char to the left
      (r!~ u~)+           Up...
      (d!~!. r~)+         Right...
      d ~,                Down...
      . r . !.
    }
  }
}

Regex (.NET), 604 517 499 469 455 bytes
^((?=[6-9](?<1>){6}|)(?=[3-59](?<1>){3}|)(?=[258](?<1>){2}|)(?=[147](?<1>)|).)+$(?<!(?=(?<-1>.)+(?(1)^))\11(?=((?<=(?=(?=((?<-2>)(?=.*$((?<-2>\2)(?<3>)|){9}).)+(?(2)^))(?>(?<-1>)(.)(?<=((?<5-1>\1)|){9}^.*))*(?<2>.(?<=((?<5>)(?<-1>\1)|){9}((?<-1>\1){10}|())((?<2-1>)(?<-3>\3)|){9}(?<-9>(?<-1>))?(?<1>){10}(?<-3>)(?<-1>)(?<5>^.*)))+$(?!\9)(?(3)^)(?<=(?<-5>(?=(?<1>(?=.*$\5)|.)).)*){10}(\12)?()|){9}^.*).)*)(?<-13>){3}^(?<-14>(?(14)|((?<2>(.)?))){10})+.*|^1)
Try it online!
Try it online! - primes matched in unary, for comparison
Takes its input in decimal, which must not have any leading zeros.
Output is in the form of "match" (prime) or "no match" (non-prime).
Processing numbers in decimal with a regex has been a very under-explored territory. Previously, the most complicated tasks that had ever been done were:

Match numbers divisible by 7
Match correct statements of addition

non-negative integers
signed numbers with optional decimal point

Matching prime numbers with a regex has been done in unary, but had never before been done in decimal.
The challenges faced here are:

All the computation of a regex must be done inside the space of the input, and its "variables" (capture groups) can only either be empty or contain substrings from the input.
The number of times a loop may iterate cannot exceed a polynomial function of the length of the input. (This limit only applies loops of continuous calculation, in which the result of each iteration must be carried on to the next. Searching for a value that fits a property can use backtracking, whose number of "iterations" can go as high as an exponential function of the length of the input, and this regex exploits that for the divisor search.)
In most regex flavors, there's no mutable data type analogous to an array. In .NET however, Balanced Groups provide what is essentially a stack data type; this can (cumbersomely) be used to emulate an array. The only way to iterate through such a stack is to destroy it, though, so every time this is done, it must be copied to another stack, in reverse order. Thus, it must be copied in reverse a second time to be reused.

I had already written a .NET regex to match primes in decimal a couple weeks before, but it must be given a hard-coded maximum bound. It's 192 bytes in length (and isn't shortened by reducing its limit from \$999\$ to \$255\$, but is shortened to 189 bytes by dropping zero-handling), and does its calculations in unary, after converting the decimal input to unary. (Its numeric variables are represented by the number of captures on each stack, being agnostic to the contents of the captures.) At the time, I thought it would be impossible to do this without a bound.
In order to match primes up to infinity, a very different algorithm must be used: actual base-encoded arithmetic, with long division. This is only possible in the .NET regex engine.
This regex captures the input in unary-coded decimal, where, on a balanced capture group that encodes a number, each digit is represented by a series of contiguous empty captures on the stack (with their count being the digit's value), and each digit is terminated by a non-empty capture. Depending on the capture group, some of them have their termination mark below each digit, and some have it above each digit; when a stack is reversed, this gets flipped. The long division is done in this data type.
Other alternatives would be converting the input from decimal to binary and then doing the arithmetic in binary, or using binary-coded decimal. I initially expected the former would turn out to be shortest, but after finishing and golfing an implementation of reading decimal input into binary, I realized that a prime regex using that would be well over 900 bytes.
.NET has a fairly obscure balanced group operation that is rarely used: (?<name1-name2>pattern). This matches (but does not capture) pattern, captures (pushes a value onto) \k<name1> as the interval from the end of the top capture on \k<name2> to the current cursor position, and then deletes (pops) that top capture from \k<name2>. If the interval is "negative", this actually causes .NET to throw an exception, Index was outside the bounds of the array, the next time that capture is used.
This regex takes advantage of the (?<name1-name2>pattern) syntax for golf reasons, using it as an equivalent for (?<-name2>)(?<name1>). It makes sure to only do this when the cursor is at the beginning of the input string, so that only empty values are pushed onto \k<name1>. This is used in two places, and I currently do not know why the first instance is working, instead of throwing the above-described exception; it seems to be that at least some of the \1 empties it pops would have been captured from elsewhere than the beginning of the string. The (?<-2>\2)(?<3>) does in fact throw this exception if an attempt is made to convert it from (?=.*$((?<-2>\2)(?<3>)|){9}) to (?<=((?<3-2>\2)|){9}^.*). As far as I know there's no debugger for .NET regex, so it may be tricky to get to the bottom of this.
When interpreting the explanation below, remember that lookbehinds in .NET, (?<=...) and (?<!...), are evaluated from right to left – so read those from bottom to top, one quantified token at a time. When entering a lookahead inside a lookbehind, go back to reading from top to bottom.
^
# Read decimal number into C1, in unary-coded decimal
(
    # Read this digit, adding it to C1
    (?=[6-9] (?<1>){6}|)  # C1 digit += 6, if digit is in [      6789]
    (?=[3-59](?<1>){3}|)  # C1 digit += 3, if digit is in [   345   9]
    (?=[258] (?<1>){2}|)  # C1 digit += 2, if digit is in [  2  5  8 ]
    (?=[147] (?<1>)   |)  # C1 digit += 1, if digit is in [ 1  4  7  ]
    .                     # C1: push separator
)+$
# C1 now has least-significant digit on top, separator above
(?<!
    (?= # Assert C1==0; since it must have the same number of separators as
        # there are digits in the input, if once we remove that number of
        # captures from it, it has nothing remaining, its value was zero.
        (?<-1>.)+
        (?(1)^)
    )
    \11 # Assert the quotient is not a power of 10 (all we really want is to
        # assert the quotient != 1, but that would be more complex to do);
        # discarding the powers of 10 other than 1 is harmless, because in those
        # cases where the remainder is zero, twice the divisor will yield half
        # the quotient and the remainder will still be zero.
    (?= # Calculate the remainder of division, letting C1 = C1 % C2:
        # C2 now has most-significant digit on top, separator above
        (                                      # C2
            (?<=
                (?=
                    # C1 now has least-significant digit on top, separator above
                    (?=                        # C3 = reverse(C2)
                        (                      # C3
                            (?<-2>)            # C2: pop separator
                            (?=
                                .*$
                                (
                                    (?<-2>\2)
                                    (?<3>)
                                |
                                ){9}
                            )
                            .                  # C3: push separator
                        )+
                        # Don't let C2 grow to be longer in digits than the
                        # input number
                        (?(2)^)
                    )
                    # C3 now has least-significant digit on top, separator above

                    # mutually align C1 with C3: C5 = reverse(C1), giving it its
                    # least-significant portion with no C3 digits to subtract
                    (?>
                        (?<-1>)                # C1: pop separator
                        (.)                    # C5: push separator
                        (?<=
                            (
                                # I'm not currently sure why "(?<5-1>\1)" can be
                                # used here as a shorthand for "(?<-1>\1)(?<5>)"
                                # but I think it has something to do with the
                                # fact that this mutually-align loop will only
                                # do a nonzero number of iterations after C2 has
                                # been padded with at least one leading zero,
                                # meaning C1 will have already been rewritten by
                                # reversing C5, i.e. we won't be dealing with
                                # the original capture of C1.
                                (?<5-1>\1)
                            |
                            ){9}
                            ^.*
                        )
                    )*

                    # \9 = borrow flag = unset = 0 (clear)

                    # C5 = reverse(C1 - C3); C2 = reverse(C3)
                    (?<2>
                        .       # C2: push separator at the end of each
                                #     iteration
                        (?<=
                            (                  # C5 digit = C1 digit
                                (?<5>)
                                (?<-1>\1)
                            |
                            ){9}
                            (
                                (?<-1>\1){10}  # C1 digit -= 10
                            |              # or...
                                ()             # \9 borrow flag = set
                            )
                            (                  # C1 digit -= C3 digit;
                                               # C2 digit  = C3 digit
                                # Using "(?<2-1>)" as a shorthand for
                                # "(?<-1>(?<2>))" works here because it is
                                # guaranteed to pull only from the captures
                                # pushed by "(?<1>){10}", which is always done
                                # at the beginning of the string.
                                (?<2-1>)
                                (?<-3>\3)
                            |
                            ){9}
                            (?<-9>             # if \9 borrow flag is set,
                                               # unset it...
                                (?<-1>)        # ...and C1 digit -= 1
                            )?
                            (?<1>){10}         # C1 digit += 10
                            (?<-3>)            # C3: pop separator
                            (?<-1>)            # C1: pop separator
                            (?<5>^.*)          # C5: push separator
                        )
                    )+$
                    (?!\9)       # Assert borrow is 0 (clear)
                    (?(3)^)      # Assert C3 has been emptied, and thus
                                 # completely processed (and by implication,
                                 # so has C1 been)
                    # C2 now has most-significant digit on top, separator above
                    # C5 now has most-significant digit on top, separator below
                    (?<=                       # C1 = reverse(C5)
                        (?<-5>
                            (?=
                                (?<1>
                                    (?=.*$\5)
                                |
                                    .
                                )
                            )
                            .
                        )*
                    ){10}
                    # C1 now has least-significant digit on top, separator above
                    (\12)?       # \11 = set if \12 is already set
                    ()           # \12 = set
                |
                    # or do nothing
                ){9}             # This digit of the quotient can range from
                                 # 0 to 9 (but we don't have to save the
                                 # quotient, just the remainder)
                ^.*
            )
            .   # pad C2 with one more leading zero
        )*
    )
    (?<-13>){3} # Assert C2 >= 2, unless C2 has a leading zero, using C13 as a
                # disposable copy of C2. The only numeric value of C2 without a
                # leading zero that puts only 2 captures on it is C2 == 1.
                # Values of C2 with leading zero(s) will cause the long division
                # algorithm to give an incorrect result, but never a false
                # positive of getting a remainder of zero, so this only results
                # in a little slowdown, testing invalid divisors.
    # C2 now has most-significant digit on top, separator above
    ^
    (?<-14>     # C13 = C2 = arbitrary number (a divisor to test)
        (?(14)|
            ((?<2>
                (.)?    # \14 = set optionally, ending incrementing of digit and
                        #      pushing a separator onto C2; due to the outer
                        #      loop being "(?<-14>)", if it still isn't set by
                        #      the last iteration of this loop, it will be.
            ))
        ){10}
    )+
    .*          # allow C2 to have fewer digits than the input
|
    ^1          # exclude 1, which is non-composite but also non-prime
)

As per the challenge rules, this does not bother to avoid matching \$0\$. But this can be fixed by changing |^1 to |^0*1? or |^[01], at a cost of 3 bytes.
Speed-improved version, 525 495 483 bytes
^((?=[6-9](?<1>){6}|)(?=[3-59](?<1>){3}|)(?=[258](?<1>){2}|)(?=[147](?<1>)|).)+$(?<!(?=(?<-1>.)+(?(1)^))\11(?=((?<=(?=(?=((?<-2>)(?=.*$((?<-2>\2)(?<3>)|){9}).)+(?(2)^))(?>(?<-1>)(.)(?<=((?<5-1>\1)|){9}^.*))*(?<2>.(?<=((?<5>)(?<-1>\1)|){9}((?<-1>\1){10}|())((?<2-1>)(?<-3>\3)|){9}(?<-9>(?<-1>))?(?<1>){10}(?<-3>)(?<-1>)(?<5>^.*)))+$(?!\9)(?(3)^)(?<=(?<-5>(?=(?<1>(?=.*$\5)|.)).)*){10}(\12)?()|){9}^.*).)*)(?<-13>){2}\13(?<-13>)^(?<-14>(?(14)|((?<2>(.)?))){10}(?<-15>))+(?<15>)(.)*|^1)
Try it online!
Try it online! - primes matched in unary, for comparison
This version limits its divisor search to \$\lceil{n\over 2}\rceil\$ digits, where \$n\$ is the number if digits in the input. This is guaranteed to go at least as high as the square root of the input number. It can test all the numbers up to \$3333\$ on TIO in 59 seconds.
Only the section that differs is explained below:
    # Assert C2 >= 2, using C13 as a disposal copy of C2:
        # The only numeric value of C2 without a leading zero that puts only 2
        # captures on it is C2 == 1
        (?<-13>){2}
        \13
        (?<-13>)
    # C2 now has most-significant digit on top, separator above
    ^
    (?<-14>         # C13 = C2 = arbitrary number (a divisor to test)
        (?(14)|
            ((?<2>
                (.)?    # \14 = set optionally, ending incrementing of digit and
                        #      pushing a separator onto C2; due to the outer
                        #      loop being "(?<-14>)", if it still isn't set by
                        #      the last iteration of this loop, it will be.
            ))
        ){10}
        (?<-15>)
    )+
    (?<15>)         # C15 += 1
    (.)*            # allow C2 to have fewer digits than the input;
                    # C15 += number digits skipped

Try it on regex101 - This is 540 503 491 bytes, as regex101 does it own validation on regexes instead of leaving that up to the engine in question, and does not currently support the (?<name1-name2>) syntax.
Regex (.NET), 692 449 396 325 bytes
^((?=(0|)).){2,}$(?<!(?=(?=((?<=(?=(?=(?<-3>(?=((?=.*$\3)|.)).)+(?(3)^))(?<-2>(?=((?=.*$\2)|.)).)*(?<-2>.(?<=(?=(?=(\2\4^|(?!\2^|\4^)|.))(?=(?<5>\7\6^|(?!\7|\6^)|.))(?(7)\2^(?!\4^)(?<-7>)|(?!\2^)\4^())?(?<3>\4^|.))^.*)(?<-4>))+$(?!\7)(?(4)^)(?<=(?<-5>(?=(?<2>(?=.*$\5)|.)).)+)|)^.*).)*)(?<-2>\2)+$)^(\B(?<3>.)|.(?<3>)){2,}.+)
Try it online!
Try it online! - primes matched in unary, for comparison
Takes its input in binary, which must not have any leading zeros. As such, it is non-competing in this challenge, which specifies that input may be taken in decimal, unary, or byte array.
The internal representation of a binary number as a capture stack is for \$0\$s to be non-empty captures, and \$1\$s to be empty captures. As such, the latter can match after the end of the string, and the former cannot.
^
# Read binary number into C2
(
    (?=
        (0|)  # C2
    )
    .
){2,}$  # at least 2 iterations to exclude 0 and 1 as non-prime
# C2 now has least-significant bit on top
(?<!
    (?=
        (?=
            (                                      # C3
                (?<=
                    (?=
                        # C2 now has least-significant bit on top
                        (?=
                            (?<-3>                 # C4 = reverse(C3)
                                (?=
                                    (              # C4
                                        (?=.*$\3)
                                    |
                                        .
                                    )
                                )
                                .
                            )+
                            # Don't let C3 grow to be longer in bits than the
                            # input number
                            (?(3)^)
                        )
                        # C4 now has least-significant bit on top

                        # mutually align C2 with C4
                        (?<-2>                     # C5 = reverse(C2)
                            (?=
                                (                  # C5
                                    (?=.*$\2)
                                |
                                    .
                                )
                            )
                            .
                        )*

                        # \7 = borrow flag = unset = 0 (clear)

                        # C5 = reverse(C2 - C4); C3 = reverse(C4)
                        (?<-2>
                            .
                            (?<=
                                (?=
                                    (?=
                                        (                # \6 = \2 xnor \4
                                            \2\4^
                                        |
                                            (?!\2^|\4^)
                                        |
                                            .
                                        )
                                    )
                                    (?=
                                        (?<5>            # C5: push bit \6 xnor \7
                                            \7\6^
                                        |
                                            (?!\7|\6^)
                                        |
                                            .
                                        )
                                    )
                                    # if \2 xnor \7, and \4 xor \7, then \7 = not \7
                                    (?(7)
                                        \2^
                                        (?!\4^)
                                        (?<-7>)          # \7 = unset borrow flag
                                    |
                                        (?!\2^)
                                        \4^
                                        ()               # \7 = set borrow flag
                                    )?
                                    (?<3>                # C3: push bit from C4
                                        \4^
                                    |
                                        .
                                    )
                                )
                                ^.*
                            )
                            (?<-4>)
                        )+$
                        (?!\7)       # Assert borrow is 0 (clear)
                        (?(4)^)      # Assert C4 has been emptied, and thus
                                     # completely processed (and by implication,
                                     # so has C2 been)
                        # C5 and C3 now have most-significant bit on top
                        (?<=
                            (?<-5>                 # C2 = reverse(C5)
                                (?=
                                    (?<2>
                                        (?=.*$\5)
                                    |
                                        .
                                    )
                                )
                                .
                            )+
                        )
                    |
                        # or do nothing
                    )
                    ^.*
                )
                .   # pad C3 with one more leading zero
            )*
        )
        # Assert C2 == 0
        (?<-2>
            \2
        )+$
    )
    # C3 now has most-significant bit on top
    ^
    (         # C3 = arbitrary number
        \B  # most-significant digit must be 1
        (?<3>.)  # C3: push 0 (non-empty)
    |
        .(?<3>)  # C3: push 1 (empty)
    ){2,}     # give C3 at least 2 bits, to force C3 >= 2
    .+        # force C3 to have at least 1 less bit than C5, making C3 < C5
)

This is witchcraft!

Prolog (SWI), 42 40 39 bytes
+X:-X>1,2+X.
Y+X:-X=<Y;0<X mod Y,1+Y+X.

Try it online!
Tests primality by checking whether any of the numbers less than the number and greater than one divide the number.

Explanation
+X:-X>1,2+X

defines a new predicate +/1 that is true if X > 1 and 2+X is satisfied. Despite what it appears, this is not an arithmetical expression. It refers to the predicate defined on the next line.
Y+X:-X=<Y;0<X mod Y,1+Y+X.

This defines a new predicate +/2 that is true if X =< Y (Y will never be greater than X, but the =< operator is one byte shorter than the =:= operator which represents equality for arithmetic expressions). If it is not the case that X =< Y then the predicate is true if both X mod Y is not zero (since X mod Y can't be negative, checking that it is greater than zero is sufficient) and 1+Y+X is true. The trick with 1+Y+X is that the two pluses do not end up being used the same way. The + operator is left associative so 1+Y+X is equivalent to (1+Y)+X. Since the expression must be a call to a predicate and +/2 is a predicate that I defined, the interpreter then calls +/2 with arguments 1+Y and X. Thus recursively the program will check whether any Y from 2 to X-1 divides X (it stops at X since X=<Y would be true and so the truth value of the others becomes irrelevant).
Operators in SWI-Prolog
This program heavily abuses the way operators are handled in SWI-Prolog. SWI-Prolog does not define predicates for arithmetic operators such as +. This makes sense since the arithmetical + is not a predicate since the output of a predicate must be true or false. What SWI-Prolog does instead is it builds structures out of the operators and then the predicates that evaluate arithmetic expressions (such as =< and <) know how to evaluate those structures. For instance after the +/2 predicate in my program recurses three times with the initial Y=2 then Y=1+(1+(1+2)) not Y=5. The fact that + is not defined as a predicate means that I can define it as a predicate myself, and since it is an operator I can save the bytes that I would otherwise need to spend on parentheses and commas.

Swift 2.0, 70 100 98 82 77 75 bytes
A simple trial division loop, divided by 2 instead of sqrt() as it takes less bytes! Will default to using 64-bit ints.
let n=Int(Process.arguments[1])!;print(n<4||(2..<n).filter{n%$0<1}.count<1)

Is there a need to divide by two? I think you can use the 2..<n range instead to save another.

This prints true for 0 and 1. You can change the condition from n<4|| to n>1&& to make it work. Also: You can change Process.arguments[1] to readLine()!

Instead of ".count<1" you can use: "==[]" to crop some extra characters.

Mouse, 65 47 bytes
?N:0S:1I:(I.N.=0=^N.I.\0=[S.1+S:]I.1+I:)S.1=!$

This uses trial division.
Ungolfed:
? N:              ~ Read an integer from STDIN and store it in N
0 S:              ~ Start a summation variable at 0
1 I:              ~ Start an interator variable at 1
( I. N. = 0 = ^   ~ While I != N
  N. I. \ 0 = [   ~ Check whether I divides N
    S. 1 + S:     ~ If so, increment the sum
  ]
  I. 1 + I:       ~ Increment the iterator
)
S. 1 = !          ~ If the sum is 1, the only divisor encountered
                  ~ is 1 (we didn't go all the way to N in the
                  ~ loop) and thus N is prime
$

May I ask what trial division is?

@BetaDecay You check the remainder when dividing by each number up to n. It's the brute force prime checking algorithm.

Dodos, 154 143 136 133 126 122 121 bytes
	N , , + > > D f f
D
	D ,
	N F > > M
M
	M m
	+ B m f
m
	F
	+ B
,
	dip F
	>
F
	+ B f
f
	+ >
	+
B
	N
N
	B dip
+
	dot
>
	dab

Try it online!
Builtins and aliases
+
	dot

This creates an alias + for the builtin function dot, which maps the vector (v1, ..., vn) to the vector (v1 + ... + vn), i.e.,
>
	dab

This creates an alias > for the builtin function dab, which maps the vector (v1, ..., vn) to the vector (v2, ..., vn).
dip

The remaining builtin, dip, maps the vector (v1, ..., vn) to the vector (|v1 - 1|, ..., |vn - 1|).
B and N
B
	N
N
	B dip

This defines a pair of mutually recursive functions. Recall that Dodos only divide or surrender.
B, if called from outside this function group, is meant to take a pair (x, y) as argument. B(x, y) simply calls N(x, y). This will always succeed, because all calls to N go through B.
N(x, y) attempts to call B(|x - 1|, |y - 1|). The tuple inequality (|x - 1|, |y - 1|) < (x, y) holds if an only if x > 0, so N(0, y) will return (0, y), since B(1, |y - 1|) surrenders.
Whenever x ≤ y, calling B(x, y) simply decrements both coordinates x times before surrendering, returning (0, y - x). If x > y, both coordinates will still be dipped x times. However, once the second coordinate reaches 0, it will cycle between 0 and 1, resulting in (0, (x - y) % 2).
N, if called from outside this function group, is meant to take a singleton (x) as argument. N(x) calls B(|x - 1|), which calls simply N(|x - 1|).
N(0) calls B(1), which attempts to call N(1). This surrenders, so B(1) returns 1, and so does N(0).
Whenever x > 0, N(x) will decrement x until reaching N(1) → B(0) → N(0) → B(1). Since B(1) surrenders, N(0)'s argument is the return value of N(x).
Thus, N(0) = 1, while N(x) = 0 whenever x > 0.
F and f
F
	+ B f
f
	+ >
	+

f returns the results of + > and + as a vector; + > takes the sum of the vector without its first coordinate, while + takes the sum f the whole vectors.
Thus, f(v1, ..., vn) = (v2 + ... + vn, v1 + ... + vn).
On occasions, we'll call f outside of F. Notably, f(x) = (0, x), f(0, x) = (x, x), and
f(x, y) = (y, x + y)
F simply calls three functions we've seen before. Since v2 + ... + vn ≤ v1 + ... + vn, B maps the result returned by f to (0, v1). + takes the sum, returning (v1).
Thus, calling F on a vector returns its first coordinate.
,
,
	dip F
	>

dip F dips the first coordinate of the argument vector, while > returns the remaining coordinates. Thus, , maps (v1, ..., vn) to (|v1 - 1|, ..., vn).
In particular, , maps (x) to (|x - 1|), so we can use it instead of dip for singleton vectors.
M and m
M
	M m
	+ B m f
m
	F
	+ B

m is always meant to be called on a pair. It simply combines a few functions we've seen before. Recall that B behaves differently if x ≤ y and if not.
We have m(x, y) = (x, y - x) if x ≤ y but m(x, y) = (x, (x - y) % 2) otherwise.
M is always meant to be called on a pair, whose first coordinate will be non-zero. M attempts to recursively call itself on the result of m. Since m doesn't change the first coordinate of its argument, we only need to examine the second one.
On the second line, B(m(f(x, y))) = B(m(y, x + y)) = B(y, x). After + takes the sum, we get x - y if x ≥ y, but (y - x) % 2 otherwise.
If y = qx, M(x, y) = M(x, qx) will successively call M(x, (q - 1)x), M(x, (q - 2)x), ..., M(x, x), M(x, 0). At the end, M(x, 0) attempts to recursively call itself, which surrenders. The return value is (x, 0), concatenated with all singletons returned by the second line. Since the second line maps (x, x) to 0, the result of M(x, y) will match the pattern (x, 0, 0, ...).
If y = qx + r, with 0 < r < x, we'll proceed in similar fashion, eventually reaching M(x, x + r), then M(x, r).

If r = 1 and x is even, m(x, r) = (x, (x - r) % 2) = (x, 1), and the recursive call to M surrenders. In the previous call, the second line mapped (x, x + r) to (x + r - x) % 2 = 1, so the result of M(x, y) will match the pattern (x, 1, 1, ...).
If r = 1 and x is odd, m(x, r) = (x, (x - r) % 2) = (x, 0), and the recursive call to M succeeds.
Likewise, if r > 1, then m(x, r) = (x, (x - r) % 2) ≤ (x, 1) < (x, r), and the recursive call to M succeeds.
In both cases, the second line will be evaluated for the last time with argument (x, t). Since we have t < r < x, the outcome is the non-zero vector (x - t), so the result of M(x, y) will match the pattern (x, ?, x - t, ...).

Thus, the third element of the vector returned by M(x, y) will be 0 if and only if x is a divisor of y.
D
D
	D ,
	N F > > M

D expects (n, n) as its initial argument.
The first line will recursively call D on the result of ,, so we'll call D(n, n) → D(n - 1, n) → ... → D(1, n) → D(0, n) → D(1, n), surrendering and returning (0, n).
The second line will be evaluated for every (k, n), with 0 < k ≤ n. F > > M calls M, discards the first two elements, then extracts the first remaining one. As we've seen before, M returns (k, ?, 1, ...) if k is a divisor of n, (k, ?, 0, ...) otherwise, so the final vector returned by D(n, n) is (0, n, 1 | n, 2 | n, ..., n | n).
main
	N , , + > > D f f

Our entry point expects a singleton (n), with n > 0.
Since f(f(n)) = f(0, n) = (n, n), D will return (0, n, 1 | n, 2 | n, ..., n | n).
After discarding (0, n) with > >, a call to + takes the sum of the Booleans, counting the number of divisors of n.
, , dips the divisor count twice, resulting in a 0 only for zero or two divisors. Since n > 0, there is at least one divisor, so the result is 0 if and only if n has exactly two divisors.
Finally, N takes the logical NOT, returning 1 for primes and 0 for non-primes.

I've edited my answer.

Not really related, but ... no chatroom for Dodos yet?

@WeijunZhou Fixed.

That's a tricky language! Some typos near the end: 0 < k < n should be 0 < k ≤ n, k | n should be n | n (two places), and "M returns 1" should be something like "M returns third element 1".

This is insane. Brain-Flak is a breeze compared to Dodos! +1

C, trial division, 72 bytes
i=1;main(n){for(scanf("%d",&n);n%++i&&i*i<n;);printf("%d",n<3?n-1:n%i);}

Note special handling for n=1,2
We need to stop the loop before i gets to n-1, so i<n-1 would do, but i*i<n is more efficient.

I used this to post a Javascript answer with the same functionality :)

You get the exact same behaviour in one byte less by just putting everything on a single line, no separator needed.

@hvd OMG! how did I miss that ?! thanks.

Replace i and n to save the initialization - when run with no arguments, the first parameter is 1.

><>, 25 + 3 = 28 bytes
:1-:v
v!?:<-1$**:@:
>r%n;

Inputting as a byte with i is shorter, but ><> can handle numbers larger than 255, hence the need for command line input in order to follow the rules. The +3 is for the v flag, i.e. run like
py -3 fish.py primes.fish -v 101

Outputs (n-1)*((n-1)!)^2 mod n (the initial (n-1)* is unnecessary, but it makes the code shorter).

I don't quite understand what you mean by your first sentence and I'm curious to know. Care to explain? The rules seem to say that it only needs to work for the integers 1 to 255.

@Cole The rules say you can read a single byte "if this is your languages largest data type"

gs2, 2 bytes
Vk

Basically read-num is-prime.

Sesos, 50 49 bytes
Algorithm #3...
0000000: 16def7 f5991b 7441bf 3f0ebb eecfd8 b86b33 b7eb33  ......tA.?......k3..3
0000015: 37ecda bccdd8 b86b33 3ffcfe 8c7de8 797cfc f599c3  7......k3?...}.y|....
000002a: f973f5 8479c5 03                                  .s..y..

Try it online!
This is the very first working code I got, so I'm sure it's possible to shave off a few more bytes here. Here's the BF-code I wrote (with some rather sparse comments that are mostly meant for myself):
,
[>+>+>+<<<-]                ; triplicate input
>>[-                        ; i from n_1 down to 0
    <+[-<<<+>>>             ; j from n down to 0 copying n to the left
        [                   ; k from j down to 1
            >[<<+<+>>>-]    ; add i to the values on the left
            <<[>>+<<-]      ; move one copy of i back
            >>>>+<<<-       ; decrement k while copying j to the right
        ]
        >>[<<+<<->>>>-]     ; subtract n from i*j while copying it
        <<[>>+<<-]          ; move n back
        >>>[<<<+>>>-]       ; move j back
        <<<<<[              ; if not equal:
            ,               ; reset to zero
            >               ; move to zero left of j
        ]
        >
    ]
    <<<[>>>+<<<-]           ; move n back to j
    >[<]>>>                 ; if we didn't exit move back to i
                            ; otherwise remain on the zero left of j
]
>,+>-[<->,]<.

I then used this Retina script to convert that to Sesos ASM:
set numin
set numout

get
jmp
   fwd 1
   add 1
   fwd 1
   add 1
   fwd 1
   add 1
   rwd 3
   sub 1
jnz
fwd 2
jmp
   sub 1
   rwd 1
   add 1
   jmp
      sub 1
      rwd 3
      add 1
      fwd 3
      jmp
         fwd 1
         jmp
            rwd 2
            add 1
            rwd 1
            add 1
            fwd 3
            sub 1
         jnz
         rwd 2
         jmp
            fwd 2
            add 1
            rwd 2
            sub 1
         jnz
         fwd 4
         add 1
         rwd 3
         sub 1
      jnz
      fwd 2
      jmp
         rwd 2
         add 1
         rwd 2
         sub 1
         fwd 4
         sub 1
      jnz
      rwd 2
      jmp
         fwd 2
         add 1
         rwd 2
         sub 1
      jnz
      fwd 3
      jmp
         rwd 3
         add 1
         fwd 3
         sub 1
      jnz
      rwd 5
      jmp
         get
         fwd 1
      jnz
      fwd 1
   jnz
   rwd 3
   jmp
      fwd 3
      add 1
      rwd 3
      sub 1
   jnz
   fwd 1
   jmp
      rwd 1
   jnz
   fwd 3
jnz
fwd 1
get
add 1
fwd 1
sub 1
jmp
   rwd 1
   sub 1
   fwd 1
   get
jnz
rwd 1
put

And of course the final conversion to binary is done by Sesos itself.
I scrapped three earlier attempts for trial division, and ultimately really got tired of the modulo computation. So I started thinking about how I could avoid that altogether. I ended up coming up with a very simple primality test, that for some reason never occurred to me before and might be handy for a lot of other esolangs where doing a multiplication is fine but computing a modulo is a royal pain:
In essence, I just compute the full multiplication between [1, ..., n-1] and [1, ..., n] starting from the largest value. After each multiplication, I subtract n from the result. If that gives 0, I terminate. This is bound to terminate, because at the beginning of the final iteration of the outer loop, I'm computing 1 * n. If I get there, it's a prime. Otherwise, some earlier multiplication will have given n and the loop stops there instead. That means I can simply check after terminating whether the first iterator is equal to 1 or not in order to decide primality.
I'll probably post the Brainfuck-version of this as well, once I'm happy with the golfing.

Cheddar, 37 bytes
Looks like a full program is required which unfortunately means a lot of boilerplate:
print Math.prime(Number::IO.prompt())

This might not work on TIO so you'd have to put it into a file and call it that way
Function, 10 bytes
Math.prime

This returns a function which checks if input is prime using Math.prime. Example:
$ cheddar primechecker.cheddar -x "[1, 3, 4, 10, 13] => (print) + f"

A full program is required.

@Dennis >_> sorry for being so late, didn't see your comment until now but fixed

Matlab/Octave 24
It is just using a builtin function, using a sieve.
disp(isprime(input('')))

You could also use this:
isprime(input(''))

Which would print the output as the last result in the console, but I am not sure whether this is allowed.

I am curious, where did you get the information about the other method that you mentioned? (Perhaps it is different in a newer vesion?)

This link I guess the MuPAD notice at the top is relevant.

Yes that is what makes the difference, thanks for the link=)

Fourier, 44 bytes
Guess who? :D
1~h2~xI~g<3{1}{5+g~g}g(g%x{0}{~hgv~x}x^~x)ho

Yes, it's my very own Fourier again, in a situation where it is actually in the running for a golfing competition.
The most bytes are spent on handling the input cases for 1 and 2.
Prints "1" for True and "0" for False.
Explanation
1~h                                            # Set h to 1
   2~x                                         # Set x to 2
      I~g                                      # Set g to user input
         <3{1}{     }                          # If accumulator is less than three then
               5+g~g                           # Add 5 and g and set g to that value
                     g(                  )     # Loop until the accumulator equals g
                       g%x{0}{      }          # If g%x equals 0, then
                              ~hgv~x           # Set h to 0 and set x to g-1
                                     x^~x      # Increment x and set x to that value
                                           ho  # Output the value of h

Python 2, 46 bytes
m=n=input()
a=1
while~-m:m-=1;a*=m*m
print a%n

Just 2 bytes shorter than the functional version: n=input();print all(n%m for m in range(2,n))*~-n. If all([]) returned False it would be the other way around.

Python 3, 52 bytes
p=n=1
exec("p*=n*n;n+=1;"*~-int(input()))
print(p%n)

Saved a byte thanks to xnor in chat.

It gives an error because there lacks a semicolon in the string. And you could save a character by removing the *n and adding a minus sign in the output.

@Labo That won't work. It would print 2 for input 4.

Yes, sorry, I forgot this case…

Is that a tadpole operator I see?

Yes! ~-x is shorter than x-1 here, because I can avoid a pair of parentheses.

ShapeScript, 53 25 23 bytes
_11?1-"@1?*@1-"1?*!?*@%

The program uses Wilson's theorem; it prints 1 for primes and 0 for non-primes. Input is in unary.
I created ShapeScript for this competition. The interpreter on GitHub has a slightly modified syntax and better I/O (none of which are required in this answer).
Try it online!
How it works
_        Take the length of the input to convert from unary to integer (N).
1        Push 1 (accumulator).
1?1-     Push a copy of N and subtract 1. Let's call the result I.
"        Push a string that, when evaluated, does the following:
  @        Swap I with the accumulator.
  1?       Push a copy of I.
  *        Multiply it with the accumulator.
  @        Swap the updated accumulator with I.
  1-       Decrement I.
"
1?       Push a copy of N-1.
*!       Repeat the string N-1 times and evaluate the result.
         This calculates (N-1)! and leaves I = 0 on the stack.
?        Use I to copy the factorial.
*        Multiply to calculate the factorial's square.
@%       Calculate N%((N-1)!*(N-1)!).

Reflections, 194 181 bytes
  _v@\
|* / (0    /\
   /;*      <
/0):\(1/# + /#+\
:  ; >~<   \ _ /
#|v\/ 1)
(0*    \#:(1 \
\\#  \(0__0) /
 _  / (0\
/^^: 0):/
\#+ _#_
/0):^\
:  / /
#
(0 >#* _#_
\ _<
   \        /

Test it!
Outputs 1 for prime, else 0.
Explanation
First we parse the number:
  _v@\
|* / (0
     *
     (1/ -> IP leaves here
     >~<
      1)
       \#:(1 \
     \(0__0) /

_ reads a line from input
v reflects the IP down
/ reflects the IP left
* at (1|1) pushes 1×1=1
| reflects the IP right
* pushes another 1
/ reflects the IP up
v pops a value off the stack and reflects the IP right as it's true
@ at (4|0) converts all input to numbers
\ reflects the IP down
(0 moves the first digit to stack 0
* at (5|2) pushes 5×2=10
(1 moves the 10 to stack 1
> reflects the IP right
~ pushes the number of left digits
< pops that number and reflects the IP down if it's not 0:

1) moves the 10 from stack 1 to the main stack
\ reflects the IP right
# redefines (0|0)
: doubles the 10
(1 moves the top 10 to stack 1 again
\ reflects the IP down
/ reflects the IP left
0) pulls the previous result from stack 0
_ at (1|1) multiplies the previous result and 10
_ at (0|1) adds the next digit
(0 pushes the result to stack 0
\ reflects the IP up
> enters the loop again

if it's zero, reflect the IP up

/ reflects the IP right

Now, we have the test number on stack 0.
Then, we initialise the loop:
            <
       /# + /

/ reflects the IP right
# redefines (0|0)
+ at (2|0) pushes 2+0=2
/ reflects the IP up
< reflects the IP left

Now, we have a 2 (the counter) on the main stack and the input number on stack 0.
Then we have the real loop:
           /\
   /;*      <
/0):\       /#+\
:  ;       \ _ /
#|v\/
(0*
\\#
 _  / (0\
/^^: 0):/
\#+ _#_
/0):^\
:  / /
#
(0 >#* _#_
\ _<
   \        /

* pushes x×y
; pops that again
/ reflects the IP down
: duplicates the counter
; discards the duplicate
\ reflects the IP right
/ reflects the IP up
\ reflects the IP left
: duplicates the counter again
0) pulls the input number from stack 0
/ reflects the IP down
: duplicates the input
# redefines (0|0)
(0 pushes the duplicated input to stack 0
\ reflects the IP right
\ reflects the IP down
_ at (1|3) pops the counter and the input and pushes whether they're equal
^ pops the test and reflects the IP left if true (i.e. if we have tested all numbers less than the input and haven't found a factor → the number is prime):

/ reflects the IP down
\ reflects the IP right
# redefines (0|0)
+ at (1|0) pushes 1+0=1
_ at (3|0) converts to string
# redefines (0|0)
_ at (1|0) prints
then the IP leaves the grid and the program ends

else the IP is reflected right:
^ reflects the IP up
# redefines (0|0)
* pushes 0×-1=0
v pops the 0 and reflects the IP left
| reflects the IP right
v reflects the IP down
* pushes 0×-1=0
# redefines (0|0)
^ pops the zero and reflects the IP right
: duplicates the counter
0) pulls the input from stack 0
: duplicates it
/ reflects the IP up
\ reflects the IP left
(0 pushes the duplicated input to stack 0
/ reflects the IP down
_ at (2|3) checks if the input is greater than the counter. Note that this is only false if the input is 1 as else the previous check applies before.
^ reflects the IP right if the check was false (i.e. input is < 2):

\ reflects the IP down
/ reflects the IP left
/ reflects the IP down
> enters the 'output zero' part, see below

else the IP is reflected left:
: duplicates the counter (once again)
0) pulls the input from stack 0 (once again)
: duplicates the input (once again)
# redefines (0|0)
(0 pushes the input to stack 0 (once again)
\ reflects the IP right
_ at (2|2) pops input and counter and pushes input modulo counter
< pops the result and reflects the IP up if 0 (it's a factor):

> reflects the IP right into the 'output zero' part, see below

else (it's no factor) the IP is reflected down:
\ reflects the IP right
/ reflects the IP up
/ reflects the IP right
# redefines (0|0)
+ at (1|0) pushes 1+0=1
\ reflects the IP down
/ reflects the IP left
_ at (0|1) adds the 1 to the counter (counter++)
\ reflects the IP up
/ reflects the IP right
\ reflects the IP down
< enters the loop again

Now for the 'output zero' part:
   >#* _#_

> reflects the IP right
# redefines (0|0)
* at (1|0) pushes 1×0=0
_ at (3|0) converts to string
# redefines (0|0)
_ at (1|0) prints '0'
then the IP leaves the grid and the program ends

Okay, I need to check out this language.

naz, 334 318 316 311 307 bytes
Original solution:
2x2v
1x0f0v1s2x0v1v1s2x1v2v3x1v0l
1x1f2v1o
1x4f0v1a2x0v1v1s2x1v2v3x1v4l
1x5f3v2x1v0f2v3x0v5l9v3x2v2g2v
1x3f5v2x0v8v2x9v3v1s2x3v5f0v3x2v1e2v2a3x3v3l8f
1x2f9v1s2x9v0v9a9a9a9a9a9a9a9a9a9a9a1a2x0v5f
1x6f1r8s8s8s8s8s8s
6f2x8v
6f5m2m2x0v
6f2x1v
2v3x1v4l0v2x5v2v2x0v
1x7f5v2x3v1s3x2v1e1s3x2v8e3f
1x8f2v1a1o
1x9f2v9a9a9a9a2x3v8v1s3x2v7l3f
9f

Only works after the current bugfixes to naz so it doesn't work here yet. As I'm not a good golfer and naz is cryptic enough, I didn't try to reduce the number of bytes further. I'm convinced there are multiple bytes to be shaved off somewhere.
Input
This program takes any three-digit natural number (001 to 999) as a command line argument in decimal representation.
Output
This program writes output: 0 for non-primes and output: 1 for primes
output:  is a constant output by the naz-interpreter that cannot be suppressed.
Truthy and falsy values don't exist in naz, as naz does not have a construct like
if(b), so I used 0 and 1 as common falsy / truthy values. One can easily change them to any other string / number by modifying 1f (for false) and 8f (for true)
How it works
naz's only datatype is a signed byte from +127 to -127. When this limit is exceeded, the interpreter halts the execution immediately. So in order to test all three digit natural numbers (including those > 127), I used 2 variables for a combined number, having the hundreds in one variable and the ones in another.
For example: The number +540 would be separated in two bytes, 5 and 40.
naz has 9 register / variables that will do all of the calculation in this program. I'll refer to them as [0] (value of variable 0) to [9] (value of variable 9). If I'm combining two variables to create a bigger number, i'll refer to it as [8]::[5] (the number generated by [8] * 100 + [5] that cannot be represented in naz's data format)
Line by Line
2x2v: initial Setup. Naz doesn't have the constant 0 anywhere, except for the accumulator at the start of each program. I decided for my whole program that [2] should be 0 to give me access to that constant.
1x0f0v1s2x0v1v1s2x1v2v3x1v0l: function f0: [0] -= [1], [1] := 0. This function assumes [1] > 0.
1x1f2v1o: f1: print 0. This is my false function. It can be modified to print any falsy value.
1x4f0v1a2x0v1v1s2x1v2v3x1v4l: f4: [0] += [1], [1] := 0. This function assumes [1] > 0
1x5f3v2x1v0f2v3x0v5l9v3x2v2g2v: f5: calculate the remainder of [9]::[0] divided by [3] by repeated subtraction. Note that there will always be the negative value of the remainder, for example 5 % 3 = -1. Also note that [9]::[0] will be destroyed in this process and [0] will contain the remainder afterwards. [3] will not be modified. Calls f0 for the subtraction and f2 to handle carry-bit arithmetic.
1x3f5v2x0v8v2x9v3v1s2x3v5f0v3x2v1e2v2a3x3v3l8f: f3: The main prime-testing function: copies [8]::[5] to [9]::[0] (as expected by f5), decrements [3] calls 5f to calculate the remainder, ends the whole loop if [0] == 0 (i.e. [8]::[5] is divisible by [3]) by calling f1, continues the loop if [3] > 2 (note that [3] is decremented before calling f5, so this will test divisible by 2 iff [3] == 3 at this point in time. Call f8 (true function) if no other conditional hit (i.e. `[0] != 0 && [3] <= 2)
1x2f9v1s2x9v0v9a9a9a9a9a9a9a9a9a9a9a1a2x0v5f: f2: The carry-bit function. reduces [9] by 1 and increments [0] by 100. Calls f5 again afterwards as conditionals in naz do not result in function calls, so there's no jump back into 5f without this.
1x6f1r8s8s8s8s8s8s: f6: The input function: as '0' is 48, subtract 48 from the character read to get its numerical value in the accumulator.
6f2x8v: Read the hundreds and write them to [8].
6f5m2m2x0v: Read the tens, multiply them by ten and write them to [0]
6f2x1v: Read the ones, write them to [1]
2v3x1v4l0v2x5v2v2x0v: Call f4 iff [1] > 0, move [0] to [5], reset [0] := 0
1x7f5v2x3v1s3x2v1e1s3x2v8e3f: f7: Handle special cases. The general idea in this program is that any 3 digit number that is not a prime has to have at least one divisor in (2, 100). However, even primes smaller than 100 will have one divisor in (2, 100), themselves. This function only gets called if [8] == 0, i.e. [8]::[5] < 100, so instead of starting at a predetermined divisor we start at [5] (note that f3 will decrement [3] before checking divisibility). If [8] == 1, we jump to f1 (FALSE), if [8] == 2 we jump to f8 (TRUE) otherwise we continue with the prime-check function 3f.
1x8f2v1a1o: f8: My true function. As with f1, can be easily modified to do whatever we want if this number is a prime.
1x9f2v9a9a9a9a2x3v8v1s3x2v7l3f: f9: Setup [3] := 36 (as 35**2 > 1000). Goto f7 iff [8] == 0 (special cases), else call f3
9f: Execute 9f.
Edits
-16 bytes by replacing 0v9a9a9a9a9a9a9a9a9a9a9a1a2x0v (30 bytes) with 2v5a4m5m2x1v4f (14 bytes) in 2f
-2 bytes by replacing 8v1s3x2v7l with 8v3x2v7e in 9f
-5 bytes by removing all unnecessary '\n' (I really, really do miss them).
That is the newline after 2x2v(1 byte), all of the initializing calls to 6f (3 bytes) and after 2v3x1v4l0v2x5v2v2x0v (1 byte)
-4 bytes by replacing 9a9a9a9a with 9a4m in 9f
Final Version
2x2v1x0f0v1s2x0v1v1s2x1v2v3x1v0l
1x1f2v1o
1x4f0v1a2x0v1v1s2x1v2v3x1v4l
1x5f3v2x1v0f2v3x0v5l9v3x2v2g2v
1x3f5v2x0v8v2x9v3v1s2x3v5f0v3x2v1e2v2a3x3v3l8f
1x2f9v1s2x9v2v5a4m5m2x1v4f5f
1x6f1r8s8s8s8s8s8s
6f2x8v6f5m2m2x0v6f2x1v2v3x1v4l0v2x5v2v2x0v1x7f5v2x3v1s3x2v1e1s3x2v8e3f
1x8f2v1a1o
1x9f2v9a4m2x3v8v3x2v7e3f
9f

I've just been sitting here inputting numbers into this program like an idiot for the past 10 minutes. Incredible job.

Actually I modified the naz interpreter to be able to write an automated script for that purpose. I can tell you there's not going to be any number <1000 with a wrong result. Although it took almost a week to make this program...

impressing the dev with their own language! +1

Minecraft 1.12.2 (expandable), 5446 bytes per bit (1-255 version: 49014 bytes)
6 wide x 16 high x 44 long structure composed of two files, pchk_v1_1_front.nbt
(3705 bytes) and pchk_v1_1_back.nbt (1741 bytes).
pchk_v1_1_front.nbt
pchk_v1_1_back.nbt

Less golfed:

8 bit version:

Notes on setting up

Each module can be pasted right next to the last one, with no gap in between.
No extra work is needed, however sometimes it is easier to replace the granite
blocks with glass before copying & pasting, then to replace them back to a
solid block afterwards. This prevents certain key observers from firing on
clone/paste/fill/etc..

When making a machine larger than 8 bits, the default timings may not be long
enough. For any delay that scales with the number of modules, a long delay
circuit is used. Increasing the
number of items in each hopper should fix the problem just fine.

Operating the machine

Input the number to be checked as a signed (two's complement) integer. Only
strictly positive inputs are valid for the challenge, but internally the
machine requires signed integers in the trial division process. Do not
change the input while the machine is running.
Connect a button to the rightmost end of the SYNC wire (pictured above) and
press it once to run the machine. There is a built-in delay right at the
start, so there is no need to wait for the machine to finish updating from
the input changing before starting.
When the left lamp turns on, the machine has finished running. The right
lamp is on when the input is prime, and off when it is not. Don't worry if
it takes a while-- at 500 TPS (using Carpet mod /tick rate), checking the
primality of the number 127 took around 7 minutes.

Explanation
Each module is composed of a few components:

Input / Number (magenta)
Divisor (light blue)
Divider (orange)
Control logic / SYNC pipeline (pink)
Output lamps, connections between components, etc.

The button pressed to start computation connects directly to the SYNC wire,
which starts the control logic on all modules on the exact same tick. The
control logic implements the following pseudocode:
<SYNC pulse>

reset output

Number == 1:
    light Done
    <end of path>

Number != 1:
    reset Divisor + lock Number into Divisor

loop:
    decrement Divisor

    ; Now, Number >= 2 and Divisor = Number - 1.
    ; We check if Divisor divides Number until it does (composite), or until
    ; Divisor is 1 (prime). We have to check the latter first each loop
    ; iteration as when Number is 2, Divisor starts at 1.

Divisor == 1:
    light Prime
    light Done
    <end of path>

Divisor != 1:
    check if Divisor divides Number

Divides:
    light Done
    <end of path>

Does not divide:
    goto loop

The divider implements its own logic as follows (repeated subtraction with State storing the current state):
divloop:
    reset State + lock Number into State
    ; Divisor is hardcoded into the divider

    ; When State - Divisor results in State's bit flipping, the T flip flop is
    ; toggled. Otherwise, State remains the same.
    update State

    State < 0:
        ; negative -> does not divide
        return DND

    State > 0:
        ; Could still be zero, keep going
        ; (no extra work needed here)

    State == 0:
        ; zero -> divides, n is composite
        return DIVIDES

    State != 0:
        goto divloop

Notes

The module could probably be golfed down quite a bit further, if anyone wants
to try.
An analog (comparator) version might be smaller and would definitely be much
faster than the current binary version.

Foo, 40 bytes
&1@@@>>&>&1<(2-1@<<@>&%+1@>>%<)&2/@>+%$i

Probably not the best approach, but I wanted to give it a try. Thanks to the "wonders" of Foo's do-while loops, I had to special case 1 and 2, both of which output errors to STDERR (but STDOUT output is correct).
The input is hardcoded as the number after the first &.

PowerShell, 35 Bytes
param($a)$a-match'^(?!(..+)\1+$)..'

Uses the same regex from Martin's Retina answer, as that's way shorter than anything that will wind up using the [math]:: libraries one would normally use. Expects input as command-line argument in unary format.
Corrected from initial version (which was apparently specific to the particular PowerShell implementation I coded it on) thanks to Jonathan Leech-Pepin. Grr undocumented version differences.
Examples:
PS C:\Tools\Scripts\golfing> .\is-this-number-a-prime.ps1 111111
False

PS C:\Tools\Scripts\golfing> .\is-this-number-a-prime.ps1 1111111
True

Bonus - PowerShell pipeline input, 29 Bytes
%{$_-match'^(?!(..+)\1+$)..'}

Same as the above, just called differently, which shaves bytes. For example,
PS C:\Tools\Scripts\golfing> 111111 | %{$_-match'^(?!(..+)\1+$)..'}
False

I actually had to wrap the $args[...]..' in () to be able to get it to resolve.  Otherwise it was always True.

@JonathanLeech-Pepin Interesting - likely a versioning difference in how operations are ordered. I primarily code in PowerShell v4 (using the ISE); what were you using?

Happened on Win7 with the latest 5.0 rtm (August), also happens on Win10 with built-in.  It is not however an issue with the pipeline version.  On the other hand: param($a)$a-match'^(?!(..+)\1+$)..' works and is exactly 35 bytes as well.

@JonathanLeech-Pepin Indeed -- I just tested and confirmed on a Windows 7 machine. How strange. Yay for undocumented features :-/ ... I've corrected the code with the param($a) iteration, which should work on any version. Thanks for the assist!

Bubblegum, 98 bytes
from math import factorial as F#
try:n=int(i)-1;o=n*(F(n)%-~n==n)
except:o=sum(map(int,i.split()))

This prints p - 1 if p is prime and 0 otherwise.
It may not look like it, but this is the shortest known Bubblegum program that achieves this task.
There are probably shorter programs, but their discovery would require a cryptographic break of the SHA-256 hash.

Did you choose the hash value based on this program or did you find it starting from a random hash?

Option 1. The program works for addition and primality testing.

Wait what according to the esolangs page this is identical to the code for calculating a sum...

@BlockCoder1392 If you give this program one number it will test primality. If you give it two or more it will add.

Perl, 23 20 bytes
say/^(?!(..+)\1+$)/

using -n option.

    say<>=~/^(?!(..+)\1+$)/

Using the regular expression+unary input approach, prints 11 (or whatever number you entered) or a blank line.
Bonus: decimal version, 31 bytes
(1x<>)=~/^1$|^(11+)\1+$/||say 1

Does this require input in unary?

@Mauris, clarified as you commented :)

The 20 byte version reports 1 as a prime, doesn't it?

The decimal version says 0 is prime.

@DanaJ The specs say it has to work on 1-255 :)  For a cost of 1 byte, changing the first part to ^1?$ would fix 0.

@MartinBüttner No, the lookahead forces a match to be at least 2 characters (= 2 or greater)

@ThaddeusB Exactly, but it's a negative lookahead, so if there's only one character, the contents of the lookahead fail, which means the lookahead itself passes and you get a match. See here

@MartinBüttner When you print the result of a regular expression in Perl, it prints the captured match ($1) instead of true/false.  So the regular expression evaluates as true for 1, but it doesn't print anything because there was no match to the (..+)

@ThaddeusB A negative lookahead shouldn't be able to capture anything (because it has to fail for the regex to match). How does this print something for primes then?

@MartinBüttner The lookahead itself doesn't capture anything, but the (..+) inside the look ahead does capture.  When the negative lookahead fails (e.g. "11" matches in "1111") $1 is cleared, when the negative lookahead goes through all the possible values without failing, the last try is left is $1 and that prints.  Since there were no ''(..+)'' match attempts for 1, nothing is ever put in $1...  There doesn't seem to be much reason as to why Perl would do this, but that is what it does.  So a prime will print 11 and a non-prime will print nothing.

@ThaddeusB Oh, that's an interesting oddity of Perl's regex flavour then. Even PCRE doesn't behave like this. I'll try to remember that. ;)

@ThaddeusB Am I correct that you read the specs as saying the program only applies to the input 1-255, and results outside that range do not need to meet the requirements?  That would impact the "probable prime" arguments for a number of other languages (since then only numbers up to 255 would have to be deterministic).  I find the relevant paragraph in the specs rather hard to interpret.

@DanaJ Good question... Per Dennis' clarification 0 failing is not an issue.

Please use the ## Perl, 19 + 1 (-n flag) = 20 bytes format as specified in the question, as I was initially confused as to why it was not counted as 19 bytes. Please also include an explanation as to why using say instead of print is allowed for free, such as is done in this answer.

say 1-(1x<>)=~/^1$|^(11+)\1+$/ is shorter than the given decimal version by 1 byte (it's 30 bytes), and has the added bonus of printing 0 instead of nothing for a "not-prime" result. But I would suggest using say 1-(1x<>)=~/^1?$|^(11+)\1+$/ which is identical in length at 31 bytes and identifies 0 as not-prime.

@ThaddeusB The link in "Per Dennis' clarification 0 failing is not an issue." is dead. I don't know what comment it originally linked to, but this comment does clarify that the input is strictly positive integers. I still think it is an interesting exercise to analyze what minimum penalty in bytes is necessary to correctly identify 0 as not-prime.

JavaScript (ES6), 47 bytes
alert(!/^(11+)\1+$/.test('1'.repeat(prompt())))

@ETHproductions OK. I'm working on the case of the input being 1.

This seems to be missing output. It assumes that the code is run in a console, i.e. a REPL environment. The challenge explicitly asks for a full program though.

Virtually identical to one already posted, which also covers the '1' case: http://codegolf.stackexchange.com/a/57692/30793

Also, needs an alert or other print function to be considered valid for code golf: http://meta.codegolf.stackexchange.com/questions/803/javascript-standards-for-io

Outputs true for 0 and 1.

FRACTRAN, 144 bytes
29/14 222/377 59/26 247/59 329/57 19/47 2/19 11/29 403/407 217/33 11/31 2/11 1/37 1/2 23/9 43/69 23/43 1/23 425/41 4823/85 17/53 41/25 2/119 1/5

This took me way longer than expected - special casing 1 was pretty annoying. Takes 5^n as input and outputs 3^0 = 1 (falsy) if composite, or 3^1 = 3 (truthy) if prime.
The approach is similar to Conway's prime generator, performing a divmod on descending divisors. This isn't as compact though, so there's still much to golf.

How does 3^1 = 7?

@feersum Updated one number, forgot to update the other. Thanks for pointing out

Sesos, 67 66 65 bytes
Edit: Saved a byte by using another get instead of a loop.
Edit: Saved a byte because I don't need this rwd 6 after I changed from sub 1 to add 1 before it.
Try it online
The hexdump:
0000000: 16f8be 76ca83 e653e3 b472f0 750ef0 af9f1f fcebbb  ...v...S..r.u........
0000015: 7f7ec6 77e13b bf41f7 2961f0 af9f1f fcebbb 7f6ec7  .~.w.;.A.)a........n.
000002a: 3fc013 ef9da3 a0fbbc 77ecc7 776e1b bf73b8 576a9c  ?........w..wn..s.Wj.
000003f: 663e                                              f>

This is the Sesos assembly code that I wrote, which is assembled into the above binary to be executed:
set numin
set numout
get

jmp     ; n += (n==2)
sub 1
fwd 1
add 1
fwd 1
add 1
rwd 2
jnz
add 2
fwd 1
jmp
sub 1
rwd 1
sub 1
fwd 1
jnz
add 1
rwd 1
jmp
fwd 1
sub 1
rwd 1
get
jnz
fwd 1
jmp
sub 1
fwd 1
add 1
rwd 1
jnz
fwd 1

jmp     ; list from n to 1
jmp
sub 1
fwd 3
add 1
rwd 3
jnz
fwd 3
jmp
sub 1
fwd 3
add 1
rwd 6
add 1
fwd 3
jnz
fwd 3
sub 1
jnz

rwd 6   ; List [n, n-1, ..., 2, 2]. We don't want n%1.
add 1
jmp
rwd 6
jnz
fwd 6

jmp     ; move n one cell to the left
sub 1
rwd 1
add 1
fwd 1
jnz

add 2   ; copy the n's
jmp
rwd 1
jmp
sub 1
fwd 3
add 1
rwd 3
jnz
fwd 3
jmp
sub 1
fwd 3
add 1
rwd 6
add 1
fwd 3
jnz
fwd 4
jnz
rwd 7

jmp     ; compute each divmod, only the n%d results will be used
jmp
sub 1
fwd 1
sub 1
jmp
fwd 1
add 1
fwd 2
jnz
fwd 1
jmp
add 1
jmp
sub 1
rwd 1
add 1
fwd 1
jnz
fwd 1
add 1
fwd 2
jnz
rwd 5
jnz
rwd 6
jnz
fwd 8

jmp     ; go to first modulus of zero, or past end of list
fwd 6
jnz

fwd 1   ; negate cell to the right
jmp
rwd 1
add 1
fwd 1
jmp
sub 1
jnz
jnz
add 1
rwd 1
jmp
fwd 1
sub 1
rwd 1
sub 1
jnz

fwd 1   ; output
put

Explanation (In BF, since I actually wrote it in BF first)
Sesos and BF are closely related, so I will write the explanation in BF to take less space (it won't be on as many lines):
>   fwd 1
<   rwd 1
+   add 1
-   sub 1
,   get
.   put
[   jmp
]   jnz

First, Sesos is basically BF, but there is some I/O help, using the assembler directives set numin and set numout. These allow me to take an unbounded integer as input, into a single cell, or output that cell as an integer. I decided this was the easiest way to write the program for all positive integers.
My explanation is of each section from the above code, with sub-explanations showing the manipulations of the tape, in an attempt to help you understand the process and algorithm. I put the tape in curly braces, and use > to denote the pointer's location on the tape.
Section 1, the bug-fix / edge case:
It should be noted that before I fixed this, my code was only 54 bytes. Because of how I determine if a number is prime later, I had to add one to n if n==2, so I do that first. I use a , here (get) to zero a cell instead of looping with [-].
[->+>+<<]++>[-<->]+<[>-<,]>[->+<]>

    n += (n==2):
    goal 1: { 2 n n }
    goal 2: { 0 n==2 n }
    goal 3: { 0 0 n* }

    { n 0 0 }
    [->+>+<<]++>
    { 2 >n n }
    [-<->]+<[>-<,]>
    { 0 >n==2 n }
    [->+<]>
    { 0 0 >n* }

Section 2, the list and my ultimate goal:
The way I check if n is prime is to check n modulo every number from n-1 to 2, which I figured would be simplest. My main goal was to reach the following data structure:
0 >{n n-1 0 0 0 0, n n-2 0 0 0 0, ..., n 2 0 0 0 0}

This facilitates the DivMod algorithm I planned to use, which requires n d 0 0 0 0 on the tape.
So I create a list from n-1 to 0, with the necessary spacing. I copy the first marked cell to the second, then copy that temp cell back into the original and into the next. Then subtract one. This repeats until I hit zero.
0 { 0 >n }
[[->>>+<<<]>>>[->>>+<<<<<<+>>>]>>>-]

0 {0 n 0 0 0 0, 0 n-1 0 0 0 0, ..., 0 2 0 0 0 0, 0 1 0 0 0 0, 0 >0 0 0 0 0}
     ^     ^      ^

Then, make the last section find n%2, since n%1 would cause a result of 0 for every n. Changing it to a zero instead of a two produces the wrong answer for n=1. After that, move back to n.
<<<<<<+
[<<<<<<]>>>>>>

0 {0 >n 0 0 0 0, 0 n-1 0 0 0 0, ..., 0 2 0 0 0 0}

Move n left one cell, preparing to copy it across the list:
[-<+>]

0 {n >0 0 0 0 0, 0 n-1 0 0 0 0, ..., 0 2 0 0 0 0}

Section 3, copy the n's
I copy n to the correct position for each entry in the list, so that I'll be ready to use the DivMod algorithm for each entry. I first add two here, so that we find another n%2, rather than n%0. This is nearly the same code as in section 2, except that I compare to the cell on the right each time, in order to stop upon completing the length of the list.
++[<[->>>+<<<]>>>[->>>+<<<<<<+>>>]>>>>]

0 {n 2 0 0 0 0, n n-1 0 0 0 0, ..., n 2 0 0 0 0, n >0 ...}
   ^     ^      ^

Section 4, compute each DivMod
I go through the list, doing the algorithm for each, after which only the n%d results are used. Though the algorithm only lists 4 cells on the site, it relies on the 5th and 6th cells being zero for its magic to work. I used the version which does not preserve n, since I won't need it anymore.
The algorithm:
# >n d 0 0 0 0
[->-[>+>>]>[+[-<+>]>+>>]<<<<<]
# >0 d-n%d n%d n/d 0 0

As applied across the list (x marks stuff I don't really need, but do make use of later):
[
    [->-[>+>>]>[+[-<+>]>+>>]<<<<<]
    <<<<<<
]>>>>>>>>

0 {0 x >n%(n-1) x 0 0, 0 x n%(n-2) x 0 0, ..., 0 x n%2 x 0 0}

Section 5, if any n%d == 0
I check the list from left to right.
{0 x >n%(n-1) x 0 0, ...}

[>]

What? You expected more? Well it really is that simple. This stops at the first occurrence of 0, which is either in this list, meaning the number is not prime, since it has a divisor, or we went past the list, and the number is therefore prime.
Section 6, negate the cell to the right and output
Uses this algorithm:
temp0[-]
x[temp0+x[-]]+
temp0[x-temp0-]

I don't need the first line, since my temp is already zero. I also use get to zero a cell instead of a loop. The last line prints the resulting number, a one if prime, or a zero if not.
>[<+>,]+
<[>-<-]
>.

Concluding remarks
Overall, this was a fun challenge. I found the mapping to BF pretty quickly with trail and error using the interpreter and the documentation. I completed it with something like 8 hours of effort. Much of the writing occurred in Notepad++ in BF that I then converted to Sesos with a Python program, tested, and debugged.
Convert BF to Sesos

Julia, 46 bytes
n=int(ARGS[1]);show(sum([n%i==0for i=1:n])==2)

An integer is read as the first command line argument using int(ARGS[1]) and the result is printed to STDOUT using show. Primality is checked using trial division with the same formulation as my R answer.
Note that the builtin function isprime uses the Miller-Rabin algorithm, which is probabilistic and is thus unsuitable for this challenge. (Thanks to Martin Büttner for pointing that out.)
Saved 4 bytes thanks to kvill.

dc, 27 bytes
?dd[d1-d1<f*]dsfxr/r2r|p

How it works (example stack for input 7):
?                             7               push input
 dd                           7 7 7           dup
   [d1-d1<f*]dsf              7 7 7 {fact}    f = factorial macro
                x             7 7 5040        execute
                 r            7 5040 7        swap
                  /           7 720           divide
                   r2r        720 2 7         swap, 2, swap
                      |       1               modular exp: 720^2 mod 7
                       p                      print output

The factorial macro breaks for input 1, or something, but it turns out not to matter, and the output is correct.

GNU sed -r, 19 18
/^(1|(11+)\2+)$/c↲

(that last ↲ isn't a literal character; it stands for a final newline).
Takes unary input on stdin.  Anything that can be represented by two or more 1s, two or more times is a composite number and replaced by an empty line.  Prime numbers are all truthy and left as-is.
There's a slight catch in that this would classify 1 as a prime (it's actually neither prime nor composite), so there are an extra 4 bytes (1|) to handle that case.
If you're willing to accept empty string as a false "output", then we could use d instead of c↲ for a further 1 byte saving.

I should have looked through the other answers before posting this - I thought I was being original and clever!

Excel, 41 bytes
=2=SUM(N(0=MOD(A1,ROW(OFFSET(A1,,,A1)))))

Takes input from A1.
4 bytes saved thanks to @Joffan!

This didn't work for me, even entered as an array formula (as I think you intended). However this array formula works: =OR(A1=2,AND(MOD(A1,ROW(INDIRECT("2:"&A1-1))))) at 47 bytes.

You sure? This works fine for me. Put the input number in A1, put the formula in another cell, and it should work.

What numbers did you try it with? 9, for example? [BTW I learned an interesting dodge from this, so thanks]

Hmm... interesting. This doesn't work for you?

No, it gives TRUE for 9 - maybe Excel version? I'm using 2010

Weird... idk. I'll look into it when I have time.

Shorter version: =2=SUM(N(0=MOD(A1,ROW(OFFSET(A1,,,A1))))) 41 bytes. (again an array formula, reporting on the value at A1)

JavaScript (ES6), 43 bytes
This is the shortest solution so far that accepts decimal input. Also, it doesn't use regex like the other short solutions.
p=n=>--d-1?n%d&&p(n):1;alert(p(d=prompt()))

What it uses instead is a recursive function, something that wasn't very useful when you needed to write function and return , but is now very useful because of the => notation.
Ungolfed:
p=n=>                 // p=function(n){ return
--d-1?                // if --d is not 1 (decrement d)
    n%d&&p(n)         // if n divdes d, false, else rerun the function
                      // (d has already been decremented)
:1;                   // else (if d is 1) then true
alert(p(d=prompt()))  // Use the function on the input
                      // and assign this value to d

One byte shorter: n%d?p(n):0 -> n%d?p(n):0

@user81655 I dont get what you mean. Did you make a typo? it's twice the same thing

Haha, I did sorry. I meant to write n%d&&p(n).

@user81655 Nice! I was looking for things like this but did'nt see it :)

Cubix, 21 bytes
%@\?I:u;>O/)((./0\)?/

Cubix is a 2-dimensional, stack-based esolang. Cubix is different from other 2D langs in that the source code is wrapped around the outside of a cube.
Test it online! Note: there's a 50 ms delay between iterations; see the browser console for current progress.
Explanation
(Note: This is somewhat confusing; I'll add a diagram with colored paths when I get a chance.)
The first thing the interpreter does is figure out the smallest cube that the code will fit onto. In this case, the edge-length is 2. Then the code is padded with no-ops . until all six sides are filled. Whitespace is removed before processing, so this code is identical to the above:
    % @
    \ ?
I : u ; > O / )
( ( . / 0 \ ) ?
    / .
    . .

Now the code is run. The IP (instruction pointer) starts out on the top left char of the far left face, pointing east. Here's an overview of the basic commands:

\|/_ are mirrors, and reflect the IP depending on the direction it's traveling.
>v<^ set the direction of the IP unconditionally.
? turns the IP right if the top item is positive, or left if it's negative.
I inputs an integer (signed or unsigned).
O outputs an integer.
: duplicates the top item.
; pops an item.
@ ends the program.

The first char we encounter is I, which inputs an integer from STDIN. : duplicates this integer. u makes the IP turn right twice, so it ends up on the no-op below u, facing west. Now it enters the main loop.
First, we need to check if this integer is less than 2, in which case it's not prime. So we decrement it twice with ((, then check its sign with the ?. If it's less than 0, the IP is turned left, in which case it wraps around to the bottom-left of the bottom panel, facing north. Removing the direction changes from the next bit, we get 0O@, which pushes a 0, outputs as an integer, and terminates the program.
If the input is more than 2, the IP is turned right at the ?. Next, the top item is incremented once with ). The IP wraps around to the % at the top-left of the top face, which pushes the modulo of the top two numbers. If the input M modulo any number 1 < N < M is 0, the number is not prime. So we check the sign of the top item with ?. If the top item is now 0, it gets output with O, then @ terminates the program.
Otherwise, the IP gets sent down to the ;, which pops the result of % since we have no further use for it. Now it's back where it started, and the loop continues until it takes a different turn at either of the ?s.
There is one more case I didn't mention before: if the sign of the top item is 0 at the first ?, that means we've run through every number 1 < N < M, which in turn means the input is prime. Since the top item must be 0, we increment it with ), then output with O and terminate the program with @.
I think this program is optimal, but I'm not certain. I'll keep looking to find a better solution.

JavaScript (ES6), 28 bytes
f=(n,i=n)=>n%--i?f(n,i):i==1

Try it online!
Old, 33 bytes:
f=(n,t=2)=>t<n?n%t?f(n,t+1):0:n>1

Mathematica, 33 bytes
Print[Mod[(#-1)!^2,#]>0&@Input[]]

or
Print[Length@Divisors@Input[]==2]

Mathematica has a built-in PrimeQ as well, but I believe it uses a probabilistic test.

What is the measurable difference between having and not having "Print@" at the front of that expression?

@EricTowers without it, it will only print when run inside a notebook, i.e. in a REPL environment. I wouldn't consider that a full program. If you invoke the code from the command line, you need the Print@ to actually get any output.

According to the documentation, PrimeQ is a deterministic algorithm.  I suspect the challenge text meant the other meaning (100% correct result).

You could save a byte with Echo.

@Pavel unfortunately, that also prints >> to STDOUT.

JavaScript, 53 52 40 bytes
alert(/^(?!(..+)\1+$)../.test(prompt()))

Just realized the question allows unary input, which cuts the size down to 40 bytes. Previous answer of 52 bytes is below (ES6):
alert(/^(?!(..+)\1+$)../.test('1'.repeat(prompt())))

Uses that cool unary regex to determine primality.
I actually originally wrote this without seeing the Retina answer, and using a different regex, as seen here: !/^1?$|^(11+?)\1+$/. I moved to the Retina one since saves a character by avoiding the need for negation.

I think this (and the other JavaScript answers) should use alert or console.log. Otherwise it's assuming a REPL environment (like a browser console) whereas the challenge explicitly asks for a full program. That said, your own regex wouldn't have been longer than mine, because you only need ^1$ (zero is not a valid input).

@MartinBüttner I agree on it needing a print statement, but when doing so puts an otherwise shorter answer behind longer ones that don't follow that rule... I chose instead to mention why I didn't. If the other answers conform, I'll gladly adjust mine as well. Thanks! =)
Good point, hadn't noticed the 0 part. It would be the same length in that case.

Well if the others think the same no one will change it. ;) You could just leave a comment (if I haven't done so already) and hope for Dennis to invalidate the answer (to remove it from the leaderboard) if the author doesn't fix it within a couple of days.

@MartinBüttner I left a comment on one of them a few days back, but fair enough haha. I suppose I could just edit them all for it as well and update the counts.

You can actually shorten the original regex by one character by making it !/^.?$|^(..+)\1+$/

Pip, 10 8 bytes
1=0Na%,a

Try it online! (testing numbers 0 through 29)
Takes the number as a command-line argument (a) and uses the definition of prime number (has only 1 and itself for factors):
      ,a  Range of numbers from 0 through a-1
    a%    Take a mod each number in range; this is 0 if the number is a divisor,
            nil if the number is 0, and nonzero otherwise
  0N      Count the number of zeros in that list
1=        True (1) if the count is exactly 1, false (0) otherwise
          Print (implicit)

Turing Machine Code, 2043 bytes
As usual, I'm using the rule table syntax defined here. Requires unary input.
0 * * r 0
0 _ _ l c
a _ 1 r b
a 0 1 r b
a 1 0 l a
b * * r b
b _ _ r 0
c 1 _ l d
c _ _ * y
d * * l d
d _ _ l a
y _ _ l y
y * * l z
z * * l z
z _ _ r X
X 1 1 r Y
Y _ _ * f
Y * * l Z
X * * l 1
Z * * l 1
1 * a r 2
2 _ b l 3
2 * * r 2
3 a a r 4
3 x x r 4
3 y y r 4
3 * * l 3
4 0 x r 5
4 1 y r 5y
4 b b l 9
9 x 0 l 9
9 y 1 l 9
9 a a r A
5 b b r 6
5 * * r 5
5y b b r 6y
5y * * r 5y
6 _ 0 l 3
6 * * r 6
6y _ 1 l 3
6y * * r 6y
A _ c l 11
A * * r A
11 b b r 12
11 x x r 12
11 y y r 12
11 * * l 11
12 0 x r 13x
12 1 y r 13y
12 c c l B
13x _ 0 l 11
13x * * r 13x
13y _ 1 l 11
13y * * r 13y
B x 0 l B
B y 1 l B
B b b r 21
21 _ d l 22
21 * * r 21
22 1 0 r 23
22 0 1 l 22
23 d d r E
23 * * r 23
E c c r 51
E x x r 51
E y y r 51
E * * l E
51 0 x r Kx
51 1 y r Ky
51 d d l 53
Kx _ 0 l E
Kx * * r Kx
Ky _ 1 l E
Ky * * r Ky
53 x 0 l 53
53 y 1 l 53
53 c c r F
F _ _ l 61
F * * r F
61 1 0 l 62
61 0 1 l 61
61 d d r 70
62 c c l 63
62 * * l 62
63 1 0 r F
63 0 1 l 63
63 b b r 80
70 _ _ l 71
70 * * r 70
71 d d l 72
71 * _ l 71
72 c c * E
72 * * l 72
80 _ _ l Za
80 * * r 80
Za 0 1 r Zb
Za 1 0 l Za
Za d d r Zk
Zb _ _ l Zc
Zb * * r Zb
Zc x x l Zc
Zc y y l Zc
Zc d d r A0
Zc 0 x l $
Zc 1 y l $y
$ d d l Ze
$ * * l $
$y d d l @
$y * * l $y
Ze 0 x r Zf
Ze 1 1 r Zk
Ze x x l Ze
Ze y y l Ze
@ 1 y r Zf
@ 0 0 r Zk
@ x x l @
@ y y l @
Zf _ _ l Zc
Zf * * r Zf
Zk _ _ l Zm
Zk * * r Zk
Zm d d l Zn
Zm * _ l Zm
Zn x 0 l Zn
Zn y 1 l Zn
Zn 0 0 r Zo
Zn 1 1 r Zo
Zo d d l 82
Zo * * r Zo
82 1 0 l 83
82 0 1 l 82
83 c c l 84
83 * * l 83
84 b b l 85
84 * _ l 84
85 a a r 86
85 x x r 86
85 y y r 86
85 * * l 85
86 0 x r &x
86 1 y r &y
86 b b l 90
&x b b r Lx
&x * * r &x
&y b b r Ly
&y * * r &y
Lx _ 0 l 85
Lx * * r Lx
Ly _ 1 l 85
Ly * * r Ly
90 x 0 l 90
90 y 1 l 90
90 a a r 91
91 c c r 51
91 * * r 91
A0 _ _ l A1
A0 * * r A0
A1 d d l A2
A1 * _ l A1
A2 x 0 l A2
A2 y 1 l A2
A2 c c r A3
A3 d d l B0
A3 * * r A3
B0 1 0 r B1
B0 0 1 l B0
B1 d d l B2
B1 * * r B1
B2 1 0 r f
B2 0 1 l B2
B2 c c r t
t * * r t
t _ _ l t2
t2 * _ l t2
t2 _ 1 * halt
f * * r f
f _ _ l f2
f2 * _ l f2
f2 _ 0 * halt

Nice! I imagine the state names could be golfed a bit more, though...

I'm still surprised this isn't actually the longest answer. (The Mornington Crescent answer is longer, which I guess makes some sense.)

Japt, 1 byte
j

Built-ins are useful for long challenges, but aren't fun in mini-challenges like this. So here's an alternate version without the built-in; still pretty short:
Japt, 8 bytes
o2 e@U%X

Try it online!
How it works
      // Implicit: U = input number. Implicitly place a U at the beginning of the program
o2    // Create an array of all integers from 2 to U. (2o6 = [2,3,4,5])
      // For numbers below 2, this returns n to 2. (2o-3 = [-3,-2,-1,0,1])
e@    // Check if every number X in this range returns truthily to:
U%X   //   the remainder of U divided by X.
      //   In other words, if any of these remainders are 0, return false.
      //   For numbers less than 2, the range contains 1,
      //   so this always returns false for these cases.
      // Implicit: output last expression

Seriously 0.1, 2 bytes
,p

, reads a value from STDIN. p pops from the stack and pushes 1 if it is prime, else 0. At EOF, all values on the stack are popped and printed.
Currently, Seriously uses trial division to test primality, so for large inputs it may take a while. In a future version, I'll probably use ECPP or Miller-Rabin.
Try it online

Seriously. Seriously?

05AB1E, 1 byte
Code:
p

Explantation:
p     # Implicit input, check whether it is prime or not.

Try it online!

@Okx Actually, that isn't necessary to state in this challenge, because this challenge explicitly states that newer languages are welcome here.

Sesos, 63 62 58 bytes
0000000: 1651bc afcddc c4fbbe 3e739e c0f1be 3673c3 eecdf8  .Q.......>s....6s....
0000015: cc75b8 677ce2 b57bc6 78cddc 796de3 7eed33 b7c113  .u.g|..{.x..ym.~.3...
000002a: ef9da3 a0fbbc 77ece7 3adc2b 354e33 f9             ......w..:.+5N3.

The ASM code that I wrote, along with some comments can be run on Try it online:
set numin
set numout
get
sub 1
jmp ; if
    add 1
    jmp ; copy
        fwd 1
        add 1
        fwd 1
        add 1
        rwd 2
        sub 1
    jnz ; end copy
    fwd 2
    sub 1
    jmp ; triplicate loop
        fwd 1
        add 1
        fwd 1
        add 1
        fwd 1
        add 1
        rwd 3
        sub 1
    jnz ; end triplicate
    fwd 1
    sub 1
    fwd 1
    sub 1
    jmp ; factorial loop
        jmp ; multiply loop
            fwd 1
            jmp ; forward add step of multiply loop
                fwd 1
                add 1
                fwd 1
                add 1
                rwd 2
                sub 1
            jnz ; end forward add step of multiply loop
            fwd 2
            jmp ; after add step, reset tape
                rwd 2
                add 1
                fwd 2
                sub 1
            jnz ; end reset tape
            rwd 3
            sub 1
        jnz ; end multiply
        fwd 1
        get ; sets to 0
        fwd 1
        jmp ; transfer intermediate value
            rwd 1
            add 1
            fwd 1
            sub 1
        jnz ; end transfer
        rwd 3
        sub 1
        jmp ; reset loop counter
            fwd 1
            add 1
            rwd 2
            add 1
            fwd 1
            sub 1
        jnz ; end reset
        rwd 1
        jmp ; fix memory location of header
            fwd 1
            add 1
            rwd 1
            sub 1
        jnz ; end fix
        fwd 2
    jnz ; end factorial
    fwd 1
    add 1
    rwd 4
    jmp ; transfer input for mod
        fwd 5
        add 1
        rwd 5
        sub 1
    jnz ; end transfer
    fwd 4
    jmp ; mod
        sub 1
        fwd 1
        sub 1
        jmp ; a
        fwd 1
        add 1
        fwd 2
        jnz ; a
        fwd 1
        jmp ; b
        add 1
        jmp ; c
        sub 1
        rwd 1
        add 1
        fwd 1
        jnz ; b
        fwd 1
        add 1
        fwd 2
        jnz ; c
        rwd 5
    jnz ; end mod
    fwd 1
    get ; sets to zero
    fwd 1
    jmp ; invert a
        rwd 1
        add 1
        fwd 1
        get ; blanks
    jnz ; end invert a
    add 1
    rwd 1
    jmp ; invert b
        fwd 1
        sub 1
        rwd 1
        sub 1
    jnz ; end invert b
jnz ; end if
fwd 1
put

I've never written any BF variant code before, outside of very simple tasks, so I'm sure some of this is not optimal. The divmod algorithm and the logical negation algorithm used were taken from the esolangs algorithms page.
This implements Wilson's theorem. We compute (n-1)! + 1 and then logically negate that value mod n. The factorial code hangs on input 1, so the code is wrapped in an if loop that totally skips running in that case. At the very end, the tape head is manipulated to be over where we would have left the mod value if we ran the code, or over some random zero if the input was 1. I'll add a more thorough explanation when I am done golfing.

brainfuck, 62 bytes
,-[+[<+>>+<-]>[-<[>+<-]<[>+>->+<[>]>[<+>-]<<[<]>-]>>>]<-[<]]<.

This is a port of my Sesos answer. Input and output are character-based. For a character whose code point is prime, the program will print the character itself; otherwise, it will print NUL.
Try it online!

Jellyfish, 13 bytes
p|&*!<
 E   i

Try it online!
Uses the squared-factorial approach based on Wilson's theorem.
Explanation
Jellyfish is Zgarb's language based on his 2D syntax challenge. The semantics are largely inspired by J, but the syntax is where it gets interesting. All functions are single characters and laid out on a grid. Functions take their arguments from the next token south and east of them and return the result north and west. This let's you create an interesting web of function calls where you reuse values by passing them into several functions from multiple directions. There are also higher-order functions called operators, which let you construct more complex functions from the built-in ones.
The only non-functions in the above code are E and &. The former redirects  |'s search for its southern argument to the east, so that | actually takes i as that input.
& applied to a single unary function (in this case *) uses the binary definition by supplying the single argument twice. Since the binary definition of * is multiplication, this yields a squaring function.
Taking these things into account, we can write up a more conventional expression:
p(i | (&* ! < i))

Here, i is just the input we're testing for primality. < decrements it, ! computes its factorial, &* squares it. | is modulo although it divides its right-hand operator by its left to compute the remainder. Hence the stuff inside the p(...) computes (n-1)!^2 % n. The p just prints the result.

I'm a little surprised how much you can do with my nonsensical collection of built-ins. :D But thanks for the praise!

This is a very genius and short code.
But moving "<" to the 2nd line makes it 1B shorter such as;
1st line: p|&*! + 2nd line:   >  <i

Mini-Flak, 202 bytes
Mini-Flak is a turing complete subset of the Brain-Flak language. (It is currently the smallest know turing complete subset of Brain-Flak)  It works exactly like Brain-Flak except the <> and [] nilads and the <...> monad are forbidden.
(({})){(({}[()])(((({}({}))[({}[{}])]([()]()))({({}[()((({}()[({})])){{}((({}({})))[{}])}{})]{})}({}{}({})[{}]))[{}]))[{}])}{}{}({}({})[{}()()()]){({}[()((({})){(({}{}(({})))[{}])}{}({}({})[{}]))]{})}{}

Try it online
Explanation
The reason <...> is banned in mini-flak is that it is equivalent to (...)[{}].  So to start this explanation I am going to use this translation in reverse to create an equivalent Brain-Flak program for increased readability for anyone who is already familiar with Brain-Flak.
(({}))
{
 (({}[()])<
  ((({}({}))[({}[{}])]([()]()))<{({}[()((({}()[({})])){{}(<({}({}))>)}{})]{})}({}{}<{}>)>)
 >)
}{}{}({}<{}>[()()()])
{({}[()((({})){(<{}{}(({}))>)}{}({}<{}>))]{})}{}

This program has two main parts, performs the modulus on the input for every number smaller than than the input and leaves them in a stack.
(({}))
{
 (({}[()])<
  ((({}({}))[({}[{}])]([()]()))<{({}[()((({}()[({})])){{}(<({}({}))>)}{})]{})}({}{}<{}>)>)
 >)
}{}{}

This uses a old version of modulo I wrote ({}(<()>)){({}[()((({}()[({})])){{}(<({}({}))>)}{})]{})}({}{}<{}>)
The second part ands together all of the results of the last part
({}<{}>[()()()])
{({}[()((({})){(<{}{}(({}))>)}{}({}<{}>))]{})}{}

If any one of the results is zero the result of all the ands will be zero otherwise it will be truthy and the number will be prime.

So you accepted my challenge, right?

J, 19 17 Bytes
echo(p:[:".1!:1)1

Explanation:
echo(p:[:".1!:1)1  | Full program.
echo(          )   | Hook: (f g) y is evaluated as y f (g y)
       [:".1!:1    | Right verb in the hook
           1!:1    | With argument 1, reads a line of input
         ".        | Evaluate, converts valid string to int
       [:          | Cap, treat these two verbs as one
     p:            | With a left argument of 1, as supplied by the hook, tests primality of its right argument
echo               | Print

I might be missing something, but 1 p: is shorter than 1=#q: (built-in primality testing isn't disallowed as far as I can tell).

Although there are several other answers that use a regex, none of them discuss the history of matching primes in this way, or show alternative regexes that match primes, or examine the range of compatibility of the regex with various engines. So that is what this post is all about.
All of the answers shown here take their input in bijective unary, as a string of x characters whose length represents the number. Output is in the form of "match" (prime) or "no match" (non-prime).
First, the shortest form:
^(?!(xx+)\1+$)

There does not exist any \$q \ge 2\$ that divides \$n\$ with a quotient of \$2\$ or greater.
Try it online!
This is the standard, well-known primality test for numbers expressed in unary. I first became aware of it when arriving upon this 14 byte form independently in the course of solving one of the levels of Regex Golf on 2014-02-12 (which kick-started my interest in regex code golf). But in there, the set of test cases only started at \$2\$ (xx), thus glossing over the fact that this regex matches the non-primes \$0\$ and \$1\$.
I later learned that this regex dates back to at least as early as a 1997-10-22 Perl post by Abigail, which then began being discussed on the next day, extending to the next two pages.
The first appearance of a regex primality test on CGCC was a 2012-01-16 answer by ChristopheD to "Finding Not-Quite-Prime Numbers".
Regex (ECMAScript or better), 16 bytes
^(?!(xx+)\1+$)xx

There does not exist any \$q \ge 2\$ that divides \$n\$ with a quotient of \$2\$ or greater, and \$n \ge 2\$.
Try it online!
The earliest I'm aware of anybody patching the regex in this way to block the matching of \$0\$ and \$1\$ is teukon in 2014-03-13. (I had previously toyed with ^(?!(xx+|)\1+$) as a patch, but this only blocks the matching of \$0\$.) Currently all of the other answers to this CGCC question that use the standard primality-testing regex, other than the Perl one, use this patched form: Retina, PowerShell, JavaScript.
It works in any engine supporting negative lookahead, which includes JavaScript/ECMAScript, Perl, PCRE, .NET, Java, Boost, Python, Ruby, and more.
Some alternative ways of testing primality avoid matching \$0\$ and \$1\$ in a conceptually and typographically cleaner way, but are longer:
Regex (ECMAScript or better), 18 bytes
^(?=(xx+?)\1*$)\1$

The smallest \$q \ge 2\$ that divides \$n\$ exists, and \$q=n\$.
Try it online!
I came up with this on 2018-12-07. This expression can be useful within a larger regex, as it automatically captures the prime in a backref, which a negative lookahead cannot do. So, (?=(xx+?)\1*$)\1$ saves 1 byte compared to (?!(xx+)\1+$)(xx+) or 2 bytes compared to (?!(xx+)\1+$)(xx+$), and uses one less capture group.
Regex (ECMAScript or better), 18 bytes
(?=(x(x*))\1+$)\2^

The largest \$q \ge 1\$ that divides \$n\$ with a quotient of \$2\$ or greater exists, and \$q-1=0\$.
Try it online!
This was arrived at first by Grimmy on 2019-04-21. I independently came up with it on 2021-03-06, basing it on my earlier finding of ^(?>(x(x*))\1+$)\2 (below).
There may be circumstances in which this could be useful in the context of a larger regex. For example, if the very first thing a regex needs to do is assert that the input is prime, without consuming any characters, this would be 2 bytes shorter than ^(?=(?!(xx+)\1+$)xx).
Regex (Perl / Java / Boost / Python / Ruby / PCRE / .NET), 18 bytes
^(?>(x(x*))\1+$)\2

The largest \$q \ge 1\$ that divides \$n\$ with a quotient of \$2\$ or greater exists, and \$q-1=0\$.
Try it online! - PCRE
I came up with this on 2018-12-07. It could conceivably be useful within the context of a larger regex. It consumes the entire prime number, like ^(?=(xx+?)\1*$)\1$, but its captures seem less likely to be useful; they are just \1=\$1\$ and \2=\$0\$. However, there may be niche circumstances where this could be coupled with NPCG (non-participating capture group) behavior, such that \1 or \2 matches if the path including the primality expression was crossed, but doesn't match otherwise. This would be equal in length to ^(?!(xx+)\1+$)xx() but capture two potentially useful optionally-unset groups instead of just one.
Regex (Tcl ARE), 16 bytes
^((x(x*))\2+$)\3

Try it online!
Tcl ARE has both positive and negative lookaheads, but neither backreferences nor captures can be done inside one. So seemingly, it would be impossible to match primes instead of non-primes.
But as it so happens, in some contexts, wrapping an expression in a capture group apparently makes it atomic (prevents the engine from doing the equivalent of backtracking into that expression if the pattern fails to match at a later point). Exactly what kind of context this requires, I have not yet determined.
This regex is based on the 18 byte PCRE regex above. Both capture groups are shifted forward by 1, so \2 is \$q\$ and \3 is \$q-1\$.

\$\large{\text{Inverted logic}}\$
In the following answers, "no match" indicates a prime, and a match indicates a non-prime.
Regex (GNU ERE or better), 14 bytes
^(xx+)\1+$|^x$

Try it online! - GNU ERE (very slow)
Try it online! - Tcl ARE
Try it online! - ECMAScript
There does not exist any \$q \ge 2\$ that divides \$n\$ with a quotient of \$2\$ or greater, and \$n \ne 1\$.
Gives a false positive for \$n=0\$. As explained below, this cannot be avoided.
Alternative form:
^((xx+)\2+|x)$

Regex (Tcl ARE or better), 15 bytes
^(xx+)\1+$|^x?$

Try it online! - Tcl ARE
Try it online! - ECMAScript
There does not exist any \$q \ge 2\$ that divides \$n\$ with a quotient of \$2\$ or greater, and \$n \ge 2\$.
Gives a correct answer for all \$n\ge 0\$. Doesn't work under GNU ERE, nor does any variation of it such as ^((xx+)\2+|x|)$ or ^(xx+)\1+$|^x$|^$. The moment the ability to match an empty string is added, it falsely matches all primes greater than \$7\$. This appears to be a bug in GNU ERE.
This form of primality test, eliminating the false positives on \$0\$ and \$1\$, dates back to at least as early as Abigail's 1997-11-18 signature on Perl Users Digest. It was not golfed at this point, and used a lazy quantifier for performance reasons (a change that occurred on 1997-10-24). This got carried over into some early CGCC answers, making them at least 1 byte longer than necessary.
The form presented here puts ^x?$ in the second alternative for performance reasons, so that it won't slow down the testing of \$n≥2\$ with the slight overhead of always trying that match first.
Alternative form:
^((xx+)\2+|x?)$

Nibbles, 4 bytes
%^`*<<,

Uses Wilson's theorem, which states that an integer \$ n \$ \$ (n > 1) \$ is prime iff \$ (n-1)! + 1 \$ is divisible by \$ n \$. To capitalize on Nibbles' implicit args feature, I slightly modified the formula to check for \$ (n - 1)!^n \bmod n > 0 \$, which also nicely handles the \$ n = 1 \$ edge case.
In Nibbles, an integer is Truthy if it is positive, and Falsy otherwise. Under this definition, checking whether the modulus is positive isn't necessary.
Ungolfed
%         # Modulo of
 ^        #  power of
  `*      #   product of
    <<,   #    [1..n-1] (implicit $)
          #   n (implicit $)
          #  n (implicit $)

Cubestack, 98 bytes
M R2 M' b' M R M' r M R' M' U2 S S' y b' M R M' r S S' y2 U M R M' D x M R M' b f2 x' y' M R' M' b

Try it Online!
Brief explanation:
M R2 M' b' M R M' r M R' M' U2 S S'  # Set up the for loop
M R2 M'                              # Push 2 to the stack
        b'                           # Get all inputs wrapped in a list
           M R M' r                  # Get the first item of the list pushed
                    M R' M'          # Push 1 to the stack
                            U2       # Range (start, end, step)
                               S S'  # Push an empty string (the loop variable)

y b' M R M' r S S' y2 U M R M' D  # Check if n is divisible the loop variable
y                                 # Open a for loop
  b' M R M' r                     # Get the first (and only) input
              S S' y2             # Get the value of the loop variable
                      U           # Perform modulo operation on the top two items
                        M R M' D  # Check if the top item equals 0

x M R M' b f2 x' y'  # If n is divisible be the loop variable, print 0 and exit
x                    # Open an if statement (code runs if top item is truthy)
  M R M'             # Push 0 to the stack
         b           # Print
           f2        # Exit program
              x'     # Finish if statement
                 y'  # End for loop

M R' M' b  # Provided that the program didn't exit in the loop, print 1

I won't explain Cubestack's syntax here, but you can see more information about this cursed language on the docs on GitHub.

floor, 105  bytes
F:x->floor x
r:x->1/(x-F x)
I:x->1+F(F x-x)
p:k->(F k*r k)+1/(r k-1)
f:n->(n-1)*I(F p^(n-2)(1+1/(n-1))/n)

returns nonzero for primes and zero for non-primes
Explanation
Ungolfed version:
intPair: x y -> x + 1/y
left: x -> floor x
right: x -> 1/(x-floor x)

is_int: x -> 1+floor(floor x - x)

fakt_1: n_k -> intPair ((left n_k)*(right n_k)) (right n_k - 1)

f: n -> (n-1)*is_int( (left fakt_1^(n-2) intPair 1 (n-1))/n)

Uses Wilson's theorem to determine if the input is a prime number
fakt_1^(n-2) intPair 1 (n-1) computes (n-1)!+1 (abusing that storing one in the second component of a pair, will increase the first component by 1)
The rest of f checks if (n-1)!+1 is evenly divisible by n and returns 1 if yes and zero otherwise.
The multiplication with (n-1) is to ensure that 1 is not falsely detected as prime
Implementation:
To run the program, execute the Python-script with the arguments
-f <source-file> -- <input-number>

floor, 116 bytes
F:x->floor x
r:x->1/(x-F x)
I:x->-F(F x-x)
s:p->I(F p/r p)*F p+1/(1+r p)
f:n->-F((1-n)/((1-n)^2+1))*F s^(n-2)(n+1/2)

returns non-zero for primes and zero for composites
Explanation:
Ungolfed version:
lt: x y -> -(floor((x-y)/((x-y)^2+1)))

intPair: x y -> x + 1/y
left: x -> floor x
right: x -> 1/(x-floor x)

not_int: x -> -floor(floor x - x)

prime_step: n_k -> intPair (not_int(left n_k / right n_k) * left n_k) (1+right n_k)
f: n -> (lt 1 n)*(left prime_step^(n-2)(intPair n 2))

prime_step takes a pair of integers (n,k) (encoded as a single rational number) as input an returns (0,k+1) if k is a divisor of n, and (n,k+1) otherwise.
f applies prime_step n-2 times to the pair (n,2) which will return 0 if n is divisible by any integer between 2 and n-1 and n otherwise.
The multiplication with lt 1 n is there to ensure that f(1) will return 0

MATLAB, 24 31 36 bytes

Changed to 31 bytes in order to add in the case of n=1
Changed to 36 bytes to make a full program and to incorporate the 1 byte saving from a suggestion by pawel.boczarski (thanks!)

Since isprime is already taken, an alternative is to take a look at the greatest common divisor of the number in question n with every number from 2 up to n-1.  If the GCD of every number in the output is 1, then the number is prime.  However, we need to check for the case of n=1, and so by definition, this shouldn't be prime:
n=input('');n-1&all(gcd(n,2:n-1)==1)

This creates an anonymous function that checks if the number is prime and assigns it to the variable f.  To call the function, simply do f(n) once it's created with n being a positive integer.
Sample Runs
>> n=input('');n-1&all(gcd(n,2:n-1)==1)
1

ans =

     0

>> n=input('');n-1&all(gcd(n,2:n-1)==1)
2

ans =

     1

>> n=input('');n-1&all(gcd(n,2:n-1)==1)
3

ans =

     1

>> n=input('');n-1&all(gcd(n,2:n-1)==1)
4

ans =

     0

>> n=input('');n-1&all(gcd(n,2:n-1)==1)
5

ans =

     1

>> n=input('');n-1&all(gcd(n,2:n-1)==1)
7

ans =

     1

>> n=input('');n-1&all(gcd(n,2:n-1)==1)
10

ans =

     0

>> n=input('');n-1&all(gcd(n,2:n-1)==1)
13

ans =

     1

>> n=input('');n-1&all(gcd(n,2:n-1)==1)
15

ans =

     0

>> n=input('');n-1&all(gcd(n,2:n-1)==1)
20

ans =

     0

>> n=input('');n-1&all(gcd(n,2:n-1)==1)
23

ans =

     1

>> n=input('');n-1&all(gcd(n,2:n-1)==1)
33

ans =

     0

>> n=input('');n-1&all(gcd(n,2:n-1)==1)
37

ans =

     1

Two tips: you can omit f= - the anonymous handle is a perfect solution (2 bytes saved), moreover in case of positive integer n~=1 can be replaced by n-1 (1 byte saved) - I tried in Octave and it worked, should work in Matlab as well.

@pawel.boczarski thanks! I had the anonymous handle but thought it conflicted with the definition of a "full program". Could you perhaps clarify on what this means?

Uhm, you're right. This is clarified in the task spec that a full program is demanded, I didn't notice that. But the tip with n-1 instead of n~=1 will still work.

@pawel.boczarski that'll shave one byte off. Thanks! Also thanks for the clarification

Lua, 56 bytes
n=io.read"*n"p=1
for i=1,n-1 do
p=p*i*i%n
end
print(p%n)

p=1 for i=1,...-1 do p=p*i*i%...end print(p%...>0) does the job in 50 bytes, by switching the input to command-line argument, and printing true and false instead of 0 and 1. Also, Be aware that 0 evaluates to true and is therefore a truthy value in lua, so your current answer technically always input true.

awk, 30 25 24 bytes
"factor "$0|getline~--NF

Prints the number followed by a colon if it's is prime, prints nothing if it's not.
I check for NF, because the output line from factor has exactly two fields if the input number is prime. The pipe command changes $0, and returns 1 on successful execution. So if NF-1=1 I know we had a prime.
You can use the ~ operator to compare two numbers, if you know that the second number would always be equal or greater.
Example usage:
echo 12347 | awk '"factor "$0|getline~--NF'

My previous idea didn't involve using system commands and is 29 bytes long:
{for(++d;$0%++d&&$0>1;);}d~$0

Prints the number if it's prime and nothing if it's not.
Example usage:
echo 12347 | awk '{for(++d;$0%++d&&$0>1;);}d~$0'

And not only because I touched the ZX81 too: if you should have only 2 fields, it has not to be the 3rd. awk '"factor "$0|getline~!$3', one character less, but it answers  prime number for 1 too (that it should be excluded), so I don't know if useful.

Prelude, 125 80 75 59 55 52 bytes
1-^ (1-v#0)#)#1+1-))(0
?(1-
 ^  ^1-( 0#v+^-( 0##10)!

For convenience, I'd suggest using my modified interpreter which reads input and prints output as decimal integers. (Otherwise, I/O would be via a single character's ASCII value.)
It turns out that simple trial division is shorter in Prelude than the squared-factorial approach, because multiplication is fairly expensive. I also found new shortest solutions to compute a modulo and a logical NOT while working on this.
Explanation
The basic algorithm is trial division: check how many numbers in [0,n-1] divide the input n via modulo (where my modulo implementation happens to return i for i%0, such that 0 is never a divisor, but doesn't crash the program either). If there was exactly one divisor (1) we have a have a prime, otherwise we don't. So the print the logical NOT of the number of divisors minus 1.
Let's go through the voices:

This voice counts the number of divisors, and is also used for the outer loop of the modulo.
This voice merely reads the input and then performs the main loop from n-1 down to 0.
This voice does the main work of the modulo computation and computes and prints the logical NOT of the number of divisors.

Finally, we can look at some parts of the code in detail:
  ^ (1-v#0)#)#

    ^1-( 0#v+^-

This is the modulo. The top voice starts by copying n from the bottom voice and the bottom voice copies the current (potential) divisor from the middle voice. The idea is to decrement both values until n is zero, but whenever the divisor hits zero we restore it.
The restoring works like this: we always copy the divisor into the top voice with v. But while the bottom voice is non-zero, we immediately discard it and push a zero instead. This value is then shifted to the bottom voice and added to the current value there.
Finally, the modulo is how far we are into the current cycle, so we subtract the divisor from the result with ^- (which is actually minus the modulo, but we only want to know if it's zero or not, so this doesn't matter).
1-     mod    1+1-))
?(1-
 ^     mod     ( 0##

This is then the main loop. The top voice is initialised to -1 (to account for the fact that 1 is always a divisor), the middle voice reads the input and the bottom voice receives a copy. Before computing the modulo, the middle voice decrements the current divisor.
After the modulo is computed we increment the counter, but decrement it again if the modulo was non-zero.
Finally, we compute the logical not, by pushing a 1 onto the bottom voice but putting a 0 on top if the divisor counter was non-zero, before printing it:
                    (0

                    10)!

APL, 21
{∧/0≠⍵|⍨(⍵≠1)+⍳|⍵-2}⎕

Trial division.  It would incorrectly state that ¯1 (minus one) is a prime but it's outside the domain so it's all right.

Welcome to Programming Puzzles & Code Golf! Because APL has its own legacy code page, we usually count APL as one byte per character here.

XSLT 3.0, 178 bytes
<transform xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:x="x" version="3.0"><template match="d" expand-text="yes">{.>1 and empty((2 to .-1)[current() mod .=0])}</template></transform>

Posted as an alternative, because it uses a significantly different approach than my previous post. In expanded form, with the usual prefixes:
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="3.0">

    <xsl:template match="d" expand-text="yes">{
        . > 1 and empty((2 to . - 1)[current() mod . = 0])
    }</xsl:template>

</xsl:stylesheet>

This method also uses a variant of my XPath solution for primality testing, which is explained there.
Since the default in XSLT is to process all nodes in the input document, this is what happens here as well. For input, you need to hand it a proper, validated XML document with a root element <d>:
<d>101</d>

The result will be output as true or false. It utilizes an XSLT 3.0 feature that allows inline XPath expressions in text nodes. It uses the XSLT 2.0 feature of schema-aware processing. If you don't have such a processor, add the XSD namespace and replace the XPath expression with the following:
. > 1 and empty((2 to . cast as xs:integer - 1)[current() mod . = 0])

For a non schema-aware processor, it would make the code at least 62 bytes larger.

Fortran 2003, 51 bytes
Here is a solution using Fortran's array capabilities. Fortran 2003 is really only required for the shorter array constructor [ ] instead of the old (/ /).
read*,n
print*,count([(mod(n,i),i=1,n)]==0)==2
end

HPR, 1217 bytes
393 bytes with macros
HPR is an unusable language I created for a challenge here.
It has only five commands, and it's not Turing complete; I was actually surprised that a primality test could be programmed in HPR.
This answer stretches the conditions of input formats a bit, since the input has to be provided as a descending list of integers from n to 1, encoded in unary and separated by 0s.
There has to be a trailing 0, so the number 4 would be encoded as 11110111011010.
The program prints 1 if the input is a prime, and an empty line if not.
Here's the source code:
$!($)(!(!(-)(#(-)())#(!(-)(#(-)()))())(!(!(-)(#(-)())#(!(-)(#(-)()))())(!(-)(#(-)())#(!(-)(#(-)())*#(!(-)(#(-)()))()!(-)(--))(*#(!(-)(#(-)()))())))!(-)(#(-)())!(-#(!(*)(#(*)())#(!(-)(#(-)()))())(!(-)(#(-)())))(#(-#(!(*)(#(*)())#(!(-)(#(-)()))())(!(-)(#(-)())))())#(-)(#(!(-)(#(-)()))())!(#(*#(!(-)(#(-)()))())(!(-)(#(-)()))-!(-)(!(!(-)(#(-)())#(!(-)(#(-)()))())(!(#(#(!($)(#(*)()#(!(-)(#(-)()))())!(-)(#(-)())*)()#(!(-)(#(-)()))())(!(-)(#(-)())))(-#(!(-)(#(-)()))())#(!(-)(#(-)()))())))(!(!(-)(#(-)())#(!(-)(#(-)()))())(!(!(-)(#(-)())#(!(-)(#(-)()))())($!($)(!(!(-)(#(-)())#(!(-)(#(-)()))())(!(!(-)(#(-)())#(!(-)(#(-)()))())(#(*)()#(!(-)(#(-)()))()))!(-)(#(-)())#(*)(!(-)(#(-)())!(-#(!(*)(#(*)())#(!(-)(#(-)()))())(!(-)(#(-)())))(#(-#(!(*)(#(*)())#(!(-)(#(-)()))())(!(-)(#(-)())))())#(-)(#(!(-)(#(-)()))()))#(!(-)(#(-)()))())!(!(-)(#(-)())#(!(-)(#(-)()))())(!(-)(#(-)())#(*)(!(-)(#(-)())!(-#(!(*)(#(*)())#(!(-)(#(-)()))())(!(-)(#(-)())))(#(-#(!(*)(#(*)())#(!(-)(#(-)()))())(!(-)(#(-)())))())#(-)(#(!(-)(#(-)()))()))#(!(-)(#(-)()))())))-#(!(-)(#(-)()))())-#(!(-)(#(-)()))())!(!(-)(#(-)())#(!(-)(#(-)()))())(!(-)(#(-)())#(!(-)(#(-)())*#(!(-)(#(-)()))()!(-)(--))(*#(!(-)(#(-)()))()))!(-)(#(-)())*#(!(-)(#(-)()))()!(-)(-)

This was not written by hand, but generated from this 393-byte source by TheNumberOne's macro system:
def d 0 !(-)(#(-)())
def l 0 #(<d>)()
def f 1 !({0})(#({0})())
def n 1 !(<d><l>)({0})
def o 2 <n>(<n>({0})){1}
def m 0 <d><f>(-#(!(*)(#(*)())<l>)(<d>))#(-)(<l>)
def x 0 <d>#(*)(<m>)<l>
def z 1 <d>*<l>!(-)(-{0})
def i 0 <d>#(<z>(-))(*<l>)
$!($)(<o>(,<m>!(#(*<l>)(<d>)-!(-)(<n>(!(#(#(!($)(#(*)()<l>)<d>*)()<l>)(<d>))(-<l>)<l>)))(<o>($!($)(<o>(#(*)()<l>,<x>))<n>(<x>),-<l>))-<l>))<n>()<z>()

Explanation
An HPR program is run in an environment, which is a set containing nonnegative integers and lists.
Initially, it contains the input list, and the five commands modify the environment in different ways.
However, it's not possible to obtain larger numbers than the maximum of the list, and it's not possible to add new elements to lists.
Thus, trial division is the way to go.
I'm not going to completely explain the code in this post, but an expanded version with comments can be found here.

Lambda Calculus, 615 bytes
(\p.(\g.(\x.g(x x))(\x.g(x x)))(\f n d.((\n.n(\x.(\x y.y))(\x y.x))((\n f x.n(\g h.h(g f))(\u.x)(\u.u))d))(\x y.x)(((\g.(\x.g(x x))(\x.g(x x)))(\f n m.((\m n.(\l r.l r(\x y.y))((\m n.(\n.n(\x.(\x y.y))(\x y.x))((\m n.n(\n f x.n(\g h.h(g f))(\u.x)(\u.u))m)m n))m n)((\m n.(\n.n(\x.(\x y.y))(\x y.x))((\m n.n(\n f x.n(\g h.h(g f))(\u.x)(\u.u))m) m n))n m))n m)(\x y.x)(((\m n.(\n.n(\x.(\x y.y))(\x y.x))((\m n.n(\n f x.n(\g h.h(g f))(\u.x)(\u.u))m)m n))n m)(\x y.y)(f((\m n.n(\n f x.n(\g h.h(g f))(\u.x)(\u.u))m)n m)m)))n d)(\x y.y)(f n((\n f x.n(\g h.h(g f))(\u.x)(\u.u))d))))p((\n f x.n(\g h.h(g f))(\u.x)(\u.u))p))

Inspired by the turing machine solution, here is a Lambda Calculus solution! You can test this code in this lambda evaluator, or in this one. The second one stops every 400 reductions so its more stable on big inputs (>11), but the first one is by far the nicest. Just paste the code in the text box and type a number behind it.
For example
(\p.(\g.(\x.g(x x))(\x.g(x x)))(\f n d.((\n.n(\x.(\x y.y))(\x y.x))((\n f x.n(\g h.h(g f))(\u.x)(\u.u))d))(\x y.x)(((\g.(\x.g(x x))(\x.g(x x)))(\f n m.((\m n.(\l r.l r(\x y.y))((\m n.(\n.n(\x.(\x y.y))(\x y.x))((\m n.n(\n f x.n(\g h.h(g f))(\u.x)(\u.u))m)m n))m n)((\m n.(\n.n(\x.(\x y.y))(\x y.x))((\m n.n(\n f x.n(\g h.h(g f))(\u.x)(\u.u))m) m n))n m))n m)(\x y.x)(((\m n.(\n.n(\x.(\x y.y))(\x y.x))((\m n.n(\n f x.n(\g h.h(g f))(\u.x)(\u.u))m)m n))n m)(\x y.y)(f((\m n.n(\n f x.n(\g h.h(g f))(\u.x)(\u.u))m)n m)m)))n d)(\x y.y)(f n((\n f x.n(\g h.h(g f))(\u.x)(\u.u))d))))p((\n f x.n(\g h.h(g f))(\u.x)(\u.u))p))
4

gives
\x y. y  ;false

And
(\p.(\g.(\x.g(x x))(\x.g(x x)))(\f n d.((\n.n(\x.(\x y.y))(\x y.x))((\n f x.n(\g h.h(g f))(\u.x)(\u.u))d))(\x y.x)(((\g.(\x.g(x x))(\x.g(x x)))(\f n m.((\m n.(\l r.l r(\x y.y))((\m n.(\n.n(\x.(\x y.y))(\x y.x))((\m n.n(\n f x.n(\g h.h(g f))(\u.x)(\u.u))m)m n))m n)((\m n.(\n.n(\x.(\x y.y))(\x y.x))((\m n.n(\n f x.n(\g h.h(g f))(\u.x)(\u.u))m) m n))n m))n m)(\x y.x)(((\m n.(\n.n(\x.(\x y.y))(\x y.x))((\m n.n(\n f x.n(\g h.h(g f))(\u.x)(\u.u))m)m n))n m)(\x y.y)(f((\m n.n(\n f x.n(\g h.h(g f))(\u.x)(\u.u))m)n m)m)))n d)(\x y.y)(f n((\n f x.n(\g h.h(g f))(\u.x)(\u.u))d))))p((\n f x.n(\g h.h(g f))(\u.x)(\u.u))p))
5

gives
\x y. x ;true

Tcl, 78 75 bytes
Thanks to sergiol
if $argv<2 {exit 1}
incr d
while {[incr d]<$argv} {if $argv%$d==0 {exit 1}}

Original version
if {$argv<2} {exit 1}
incr d
while {[incr d]<$argv} {if {$argv%$d==0} {exit 1}}

Works for all integer values (both negative and arbitrarily large). However, as this aims to be short and not efficient, it is written with a simple divisor={2,3,4,...} loop, so you'll begin getting noticeable lag around eight digit numbers (n ≥ 108).
The input is taken on the command-line; the output is an exit code: 0 for prime and 1 for not prime.
On Windows you can use the following batch file to test it:
@echo off
tclsh a.tcl %1
if ERRORLEVEL 1 (
  echo not prime
) else (
  echo prime
)

Use it as:
C:\foo> run.bat 2017
prime

On *nixen you can use the following bash script to test it:
#! /bin/sh
tclsh a.tcl $1
if [ $? -eq 0 ]
then
  echo prime
else
  echo not prime
fi

Use it as:
% ./run.sh 2017
prime

Enjoy!

You can save some bytes: https://tio.run/##K0nO@f8/M01BJbEovczGSKE6tSKzRMGwliszL7lIIYWrPCMzJ1WhOhrCjbUBq6tVqAZqUQSzVVVS4Jpq//8HAA

Please be careful to test stuff before suggesting edits. ! has higher precedence than %, so the ==0 remains... Other edits made from your suggestion. Thanks!

I tested it on my local machine and it seemed to work

Nobody else is testing the validity of the inputs, so you can remove the 1. line.

Sesos, 28 24 bytes
0000000: 1651b8 77cd1c 345e33 c67bbe c673b8 676c38 67fe98  .Q.w..4^3.{..s.gl8g..
0000015: 70e201

Uses trial division. Try it online! Check Debug to see the generated binary code.
How it works
The binary file above has been generated by assembling the following SASM code.
set numin     ; Switch to numeric input.
set numout    ; Switch to numeric output.

get, sub 1    ; Read an integer n from STDIN and decrement it.
              ; If n is 1, this will leave a 0 in cell 0.
jmp           ; While loop entry point; if the cell is 0, skip the loop body.
    add 1     ; Add 1 to restore n.

    ; The following is the actual primality test. To see how it works, consult the
    ; corresponding section of this answer.

    jmp, rwd 1, add 1, fwd 2, add 1, rwd 1, sub 1, jnz
    fwd 1
    jmp
        sub 1, rwd 1
        jmp, fwd 1, add 1, rwd 1, sub 1, jnz
        rwd 1
        jmp
            fwd 1, add 1, fwd 1, sub 1, fwd 1, add 1, rwd 1
            jmp, fwd 1, jnz
            fwd 1
            jmp, rwd 1, add 1, fwd 1, sub 1, jnz
            rwd 2
            jmp, rwd 1, jnz
            fwd 1, sub 1
        jnz
        fwd 3
    jnz
    rwd 1, sub 1
    jmp, rwd 1, jnz

jnz           ; While loop exit marker; since the previous instruction also sets
              ; an exit marker, the current cell will be 0 and we exit the loop.
rwd 1, put    ; Retrocede to the previous cell and print its content to STDOUT.
              ; If n > 1, this will print the result from the primality test.
              ; If n = 1, it will simply print 0.

Modulus computation
The core of this answer is its modulus algorithm, which is based on the divmod algorithm from Esolangs. Unlike the latter, it doesn't compute a quotient and works if the divisor is 1.
Suppose the tape in in the following state, where n and d are positive integers.
  v
  n     0     d     0     0     0

To compute n % d, we will decrement the third cell n times. Each time we decrement it, we also increment the fourth cell (so their sum is d at all times), and swap their contents every time the third cell reaches 0.
We have to decrement the first cell once for each iteration, and stop once it reaches 0. Since this will destroy the content of the first cell, we'll also increment the second cell once for each iteration, effectively copying n to the second cell.
Once the first cell reaches 0, the tape will be in the following state.
  v
  0     n   d-n%d  n%d    0     0

We achieve this as follows.
jmp           ; While the first cell is non-zero:
    fwd 1     ;     Advance to the second cell.
    add 1     ;     Increment it.
    fwd 1     ;     Advance to the third cell.
    sub 1     ;     Decrement it.
    fwd 1     ;     Advance to the fourth cell.
    add 1     ;     Increment it.
    rwd 1     ;     Retrocede to the third cell.
    jmp       ;     While the current cell in non-zero.
        fwd 1 ;         Advance to the next cell.
    jnz       ;     This will advance to the fifth cell if the third is non-zero
              ;     and stay on the third cell otherwise.
    fwd 1     ;     Advance either to the fourth or sixth cell.
    jmp       ;     While the fourth/sixth cell is non-zero:
        rwd 1 ;         Retrocede to the third/fifth cell.
        add 1 ;         Increment it.
        fwd 1 ;         Advance to the fourth/sixth cell.
        sub 1 ;         Decrement it.
    jnz       ;     This will add the fourth/sixth cell to the third/fifth cell,
              ;     zeroing the former in the process. Since the sixth cell has a
              ;     value of 0, this loop is a no-op if the third cell in 0; other-
              ;     wise, it sets the third cell to d and the fourth cell to 0.
    rwd 2     ;     Retrocede to the second/fourth cell.
    jmp       ;     While the current cell is non-zero:
        rwd 1 ;         Retrocede to the previos cell.
    jnz       ;     This places the head to the left of the first cell.
    fwd 1     ;     Advance to the first cell.
    sub 1     ;     Decrement it.
jnz           ;

Primality test (WIP)
For input n > 1, we can use the modulus algorithm from the previous section to implement a primality test by trial division.
If n is already on the tape, we procede as follows.

Create a copy of n and decrement it to leave the tape as
                  v
      n     0     d     0     0     0

where d = n - 1.
Retrocede to n and use the modulus algorithm to compute n % d, leaving the tape as follows.
      v
      0     n   d-n%d  n%d    0     0

Advance to the cell containing n % d.

If n % d > 0, add d - n % d to n % d to restore d, decrement it, and go back to step 2.
If n % d = 0, we found the first divisor of n (1 for primes); go to step 4.

Since n % d = 0, d - n % d = d.
We retrocede to that cell, decrement it to leave d - 1 in it (0 if and only if n is prime), and retrocede until finding the first 0 cell. This leaves the tape as
             v            V
      0      0     n     d-1   0    0     0

where v marks the location of the tape head if d - 1 > 0, and V the location if **d - 1 = 0.
Note that the value of the cell under the tape head will be 0 in either case. The cell to the left will contain n if n is prime, and 0 if n is composite.

You should add the BF version of your modulus algorithm to the Esolangs page.

Done.

CASIO-BASIC, 28 bytes
?->A:For 2->B To A:A Rmdr B=0=>B->A:Next

This prompts for a number, then outputs the number if it is prime, else zero.
I'm not really sure how this works. I originally thought it would output the value from the last assignment (stored in Ans), but then it would output the lowest factor of the number, not zero.
Note: -> and => are ASCII representations of one symbol each (the assign-to and conditional operators).
The size was calculated as the size of this program (60 bytes) minus the size of an empty program (32 bytes).

WolframAlpha, 10 bytes
isprime(n)

haha, this is interesting...

Save some bytes with 'n prime'.

Logicode, 601 511 467 bytes
circ o(n)->cond n<->0+n/o(n>)
circ p(n)->[
cond n->var c=~((~(o(n)))>)/var c=0
cond (~n)<->var d=p(c)+0/var d=c+1
d
]
circ q(n)->[
cond n->var e=~((~(o(n)))>)/var e=0
cond (~n)<->var f=e+0/var f=q(e)+1
f
]
circ r(a,b)->cond *a&*b->r(q(a),q(b))/a
circ s(a,b)->!(*(r(b,a)))
circ t(a,b)->cond b->t(q(a),q(b))/a
circ u(a,b)->cond s(a,b)->u(t(a,b),b)/!(*a)
circ v(a)->[
var j=p(j)
cond s(a,j)->[
var k=k+u(a,j)
var l=v(a)
]/[
var k=k
]
*((~k)>)
]
var j=1
var k
out v(binp)

Oh my, that is a lot of code.
Here's a rundown of what each circuit does:

o is a trimmer, and it strips the extra 0's at the start (this is used for p and q.
p is a successor, and q is a decrement.
r is a preliminary bit to s (lessthan).
s is the lessthan (which uses the remainder checker).
t is a subtractor, which calculates a - b for any two positive integers a and b (in binary).
u is a mod checker, which returns 1 if a%b is not 0, and 0 if it is 0.
v is the actual prime checker, which returns 1 if the number is not prime, and 0 if the number is.

The j and k at the bottom are the divisor (b in the mod checker) and the un-bool'd output respectively.

The final line is the "input" bit, which asks for user input in binary (any other character that is not 0 or 1 in the input will be ignored), and returns 1 if the result is not prime, and 0 if the result is.
Edit 1: Saved a whopping 90 bytes (implemented circ/cond one-liners).
Edit 2: Saved another 44 bytes (implemented boolean operator, multi-line conds, and null variables).

Dyalog APL, 10 9 bytes
2=∘≢∘∪⍳∨⊢

I don't think this one has been posted.

Symbolic Python, 48 bytes
___=_
__("__=_/_"+";_=-~_;__*=_*_"*~-_)
_=__%___

Try it online!
Uses Wilson's theorem, i.e. that \$(n-1)!^{2} \% n = 1\$ if \$n\$ is a prime, otherwise it equals \$0\$.
Explanation:
___=_                              # Save the value of input to ___
__(                             )  # Evaluate string
   "__=_/_"                        # Initialise __ as 1
           +";             "*~-_   # Then repeat n-1 times
              _=-~_;               # Decrement n
                    __*=_*_        # Multiply __ by n squared
_=__%___                           # Output the value of __ modulo ___

Alchemist, 126 bytes
_->In_a
a->b+c
0e+b+c->g+h
f+0c+b->e+b
e+0h+c->f+c
f+0b+c->c
0e+0f+g->b
0f+h+0s->c
0f+0a+0g+0h+c->f
f+0b+0c+h->s
s+0h->Out_"1"

Try it online!
Outputs 1 for primes, and nothing for composite numbers. Here's a script that tests the program against numbers below 100.
This is rather inefficient, as I removed a restriction that prevented one rule undoing another rule for a sweet one byte save (worth it!). To be much more efficient, we can replace the 0e in the third rule with f and add f to the other side too. Try it online!
Explanation:
_->In_a           # Create the input number of a atoms
a->b+c            # Convert all them to b and c atoms
                  # b will serve as a permanent save of the input
                  # c will be a counter starting at the input

0f+0a+0g+0h+c->f  # Decrement c and start the main loop by setting the f flag
# Note that f and 0e are mostly interchangeable, and the same with 0f and e
0e+b+c->g+h       # Subtract the counter from the input, keeping a copy of both
f+0c+b->e+b       # When the counter runs out, set the e flag
0f+h+0s->c        # Move the temporary counter atoms back to the main counter
e+0h+c->f+c       # Once done, set the f flag again
f+0b+c->c         # If the counter isn't 0 when the input reaches 0
                  # Then the input is not divisible by the counter

0e+0f+g->b        # Convert the temporary input atoms back to the main input
                  # Reuse the temp counter to main counter rule again

# Once both are done, start the loop over again, decrementing the counter
# This continues until:

f+0b+0c+h->s      # If both the counter and the input reach 0 at the same time
                  # Then the input is currently divisible by the counter
                  # Decrement the temporary counter atom
s+0h->Out_"1"     # If the temp counter is 0 after that (i.e. the highest factor is 1)
                  # Print 1

Java, 108 bytes
interface P{static void main(String[]a){long l=new Long(a[0]),i=1;for(;0<l%++i%l;);System.out.print(l==i);}}

Try it online!
Port of my Ink answer. Would beat all existing answers in C#, Python (2 and 3), and possibly other languages if ported.
Ungolfed
interface PrimeChecker {
    // Unlike members of classes, members of interfaces are public by default.
    static void main(String[] args) {
        long input = new Long(args[0]),
             div = 1;
        for (; 0 < (  input % (++div) // Trial division, finish when div divides input
                    % input           /* If input is at least 2, this has no effect.
                                         But (1 % n) = 1 for any n > 1
                                         so without this, the loop would never end
                                         when the input is 1 */
                   );
            ) { /* The loop body is empty, we're just using it to set div */ }
        // div is now the lowest number greater than 1 that divides the input
        // (or 2, if the input is 1)

        // The input is prime iff that number is equal to the input
        System.out.println(input == div);
    }
}

Note for those who, like me, didn't understand the existence of the last %l at first, it's to shortcut the loop when the input is 1.

Google Sheets, 29 bytes
=mod(fact(A1-1),A1)=mod(-1,A1

Try it on my Google Sheet
It uses Wilson’s theorem, which, in modular arithmetic, is:
(n − 1)! ≡ −1 (mod n)

read: n − 1 factorial is congruent modulo n to negative 1
However, it is important to maintain the distinction between (mod n) notation and and the modulo operator. We could rewrite Wilson’s theorem using more familiar mod operators:
(n − 1)! % n = -1 % n

and that’s what i wrote into google sheets. Google Sheets also does parenthesis autocompletion, so i omitted the final parentheses.

Vyxal, 3 bytes
KḢ₃

Try it Online!
I thought something non trivial would be nice for a change. æ does the job for one byte but where's the fun in that?
-1 thanks to EmanresuA
Explained
KḢ₃
KḢ   # factors(input)[1:]
  ₃  # len(^) == 1 // prime numbers have only [1, n] as factors...other numbers have 1 or 3+ factors

This can be KḢ₃

Also, 5 bytes version with no factorisation - 4 with r if you remove the $

Taxi, 1238 bytes
Go to Post Office:w 1 l 1 r 1 l.Pickup a passenger going to The Babelfishery.Go to The Babelfishery:s 1 l 1 r.Pickup a passenger going to Cyclone.Go to Cyclone:n 1 l 1 l 2 r.Pickup a passenger going to Cyclone.Pickup a passenger going to The Underground.Go to The Underground:n 2 r 2 r.Switch to plan q i.[l]Pickup a passenger going to Cyclone.Go to Zoom Zoom:n 3 l 2 r.Go to Cyclone:w.Pickup a passenger going to Divide and Conquer.Pickup a passenger going to Sunny Skies Park.Pickup a passenger going to Divide and Conquer.Go to Sunny Skies Park:n 1 r.Go to Divide and Conquer:n 1 r 1 r 2 r 1 r.Pickup a passenger going to Cyclone.Go to Cyclone:e 1 l 1 l 2 l.Pickup a passenger going to The Underground.Pickup a passenger going to Equal's Corner.Pickup a passenger going to Trunkers.Go to Trunkers:s 1 l.Pickup a passenger going to Equal's Corner.Go to Equal's Corner:w 1 l.Switch to plan c i.Go to The Underground:n 3 r 1 r 2 l.Switch to plan p i.[q]0 is waiting at Writer's Depot.[p]1 is waiting at Writer's Depot.Go to Writer's Depot:n 3 l 2 l.Pickup a passenger going to Post Office.Go to Post Office:n 1 r 2 r 1 l.[c]Go to Sunny Skies Park:n.Pickup a passenger going to Cyclone.Go to The Underground:n 1 r 1 r 2 r.Switch to plan l.

Try it online!

With many ideas from this answer, but 1 character shorter using the same shortening techniques.note
This takes a slightly different approach so that “The Underground” is the return point for each iteration instead of “Zoom Zoom”.
Even though this ends up only 1 character shorter, it's actually one whole instruction shorter!
The reduction is relatively little because there's 2 more turns and “The Underground” is mentioned more.
The ways this answer has golfed more than the linked answer are as follows:

Removing all quotes around plans and strings.
As long as there is no space or other special character they are not needed.
For the Switch to plan "name" if no one is waiting the only check is whether there is any text after "name".
This means that the  if no one is waiting part can be replaced with  i.
If we did use quotes like the original answer we could also remove the spaces after closing quotes.

This is the code ungolfed with some comments.
    [Read number and convert to int]
Go to Post Office: west 1st left, 1st right, 1st left.
Pickup a passenger going to The Babelfishery.
Go to The Babelfishery: south 1st left, 1st right.

    [Duplicate to get numerator and denominator]
Pickup a passenger going to Cyclone.
Go to Cyclone: north 1st left, 1st left, 2nd right.

    [Decrement denominator and duplicate both]
Pickup a passenger going to Cyclone.
Pickup a passenger going to The Underground.
Go to The Underground: north 2nd right, 2nd right.
Switch to plan "not prime" if no one is waiting.
[loop]
Pickup a passenger going to Cyclone.
Go to Zoom Zoom: north 3rd left, 2nd right.
Go to Cyclone: west.

    [Pickup for division...]
Pickup a passenger going to Divide and Conquer.
Pickup a passenger going to Sunny Skies Park.
Pickup a passenger going to Divide and Conquer.
Go to Sunny Skies Park: north 1st right.
Go to Divide and Conquer: north 1st right, 1st right, 2nd right, 1st right.
Pickup a passenger going to Cyclone.
Go to Cyclone: east 1st left, 1st left, 2nd left.

    [Copy result to check if integer, first pickup ]
Pickup a passenger going to The Underground.
Pickup a passenger going to Equal's Corner.
Pickup a passenger going to Trunkers.
Go to Trunkers: south 1st left.
Pickup a passenger going to Equal's Corner.

    [Check if integer]
Go to Equal's Corner: west 1st left.
Switch to plan "continue" if no one is waiting.
Go to The Underground: north 3rd right, 1st right, 2nd left.
Switch to plan "prime" if no one is waiting.

    [Print whether it's a prime or not]
[not prime]
0 is waiting at the Writer's Depot.
[prime]
1 is waiting at the Writer's Depot.
Go to Writer's Depot: north 3rd left, 2nd left.
Pickup a passenger going to Post Office.
Go to Post Office: north 1st right, 2nd right, 1st left.

    [Pickup numerator and decrement denominator for checking lower numbers]
[continue]
Go to Sunny Skies Park: north.
Pickup a passenger going to Cyclone.
Go to The Underground: north 1st right, 1st right, 2nd right.
Switch to plan "loop".

Try it online!

<>^v, 184 bytes
Prints 1 if number is prime, otherwise 0.
>]v2i>IT%0=vIT[vv
             > vv
1          I   TI
T          T    )
T          =    i
t          > ^  v
,    ^          <
               v
               >"1";
  >        >"0";
^@|

Explanation
@  Pointer starts here, goes right
|  Mirror — reverse pointer direction
@  No-op because the program is already running
^  Send instruction pointer up
,  Read number from stdin and push to stack
t  Pop and store in variable `t`
T  Push value of variable `t`
T  Same
1  Push 1
>  Send instruction pointer right
]  If top element of stack is greater or equal to the second element of the stack
  v  Send instruction pointer down
  >  Send instruction pointer right
  Go to [not prime]
Else
2  Push 2
i  Pop and store into variable `i`
[loop start]
>  Send instruction pointer right
I  Push value of variable `i`
T  Push value of variable `t`
%  Set top of stack to top of stack modulo second element of stack
0  Push 0
=  If the top two elements of the stack are equal
  v  Send instruction pointer down
  I  Push value of variable `i`
  T  Push value of variable `t`
  =  If the top two elements of the stack are equal
    >  Send instruction pointer right
    ^  Send instruction pointer up
    >  Send instruction pointer right
    Go to [prime]
  Else
[not prime]
    >  Send instruction pointer right
    "0"  Push "0"
    ;  Print top of stack
    ';' was the last character of this row, program exits
Else
I  Push value of variable `i`
T  Push value of variable `t`
If the first element of the stack (t) is smaller or equal to the second element of the stack (i)
  v  Send instruction pointer down
[prime]
  v  Send instruction pointer down
  T  Push value of T
  v  Send instruction pointer down (there only to ensure the row is long enough)
  >  Send instruction pointer right
  "1"  Push "1"
  ;  Print top of stack
  Since ';' was the last character of the row, exit
v  Send instruction pointer down
v  Idem
I  Push value of variable `i`
)  Increment top of stack
i  Pop stack and store in variable `i`
v  Send instruction pointer down
<  Send instruction pointer left
^  Send instruction pointer up
Go to [loop start]

More simply, it first checks if the number is lower or equal to 1. If so, it prints 0 and exits. Then, it sets the variable i (current divisor) to 2. Then the program enters a loop.
In that loop:

If the number modulo i is 0:

If i == number, print 1 and exit (prime). Else, print 0 and exit (has found a divisor, number isn't prime).

Then it increments i, and goes back to the beginning of the loop.

run online

Trilangle 1.3, 31 29 bytes
<'?<#2%._zS<.>(>.,)2-/\\_/!@@

Reads a single integer from STDIN, and prints 0 iff it's prime.
Try it on the online interpreter!
TL;DR
Keeps a running counter that starts at 2, and increments it until (input % counter) == 0. Then, it prints '0' if input == counter.
What is Trilangle?
Trilangle is a 2-D stack-based programming language. Program flow can be redirected with "mirrors" /|\_ or with branches <^7>vL. The branches can split, merge, or reflect control flow, depending on how they're used. If the IP walks off the board, it continues one row or diagonal to its left.
Code Explanation
Unfolds to this example from the README:
       <
      ' ?
     < # 2
    % . _ z
   S < . > (
  > . , ) 2 -
 / \ \ _ / ! @
@ . . . . . . .

Equivalent to this C code:
#include <stdio.h>

// Get an integer from stdin. Implementation provided by the interpreter.
extern int getint(void);

int main() {
  // RED PATH
  int input = getint();
  int counter = 2;
  while (input % counter)
    // GREEN PATH
    ++n;
  // BLUE PATH
  if (input == counter)
    // YELLOW PATH
    return 0;
  // MAGENTA PATH
  puts("0");
  return 0;
}

This uses the new 2DUP instruction z to make stack management easier: it copies both the input and counter so that they may be operated on non-destructively. The older version below used a combination of j (indexed read), 2 (duplicate), and S (swap) to achieve a similar effect.
Older answer: Trilangle 1.0,  42  41 40 bytes
'2.?..<_.@j.2'2,<|>(%!.\S)S,,)S<.....@>-

Ruby, 16 + 6 = 22 bytes
[*$<];p$..prime?

or equivalently
p$<.count.prime?

Rules abuse! Kind of, anyway. This answer requires that the input be in unary, and that the character used for input be a newline. Invoke like
ruby -rprime prime_test.rb input

Where input is a file containing n newlines.
I calculate this at 22 bytes: 6 for "rprime" and 16 for the code. However, I also calculate manatwork's answer at 22 bytes if you golf the command line invocation (7 for 'nrprime' and 15 for the code).

Are you sure that Ruby's prime? doesn't use a probabilistic test?

Yes, it loops through a pseudoprime generator (which returns a superset of the primes) and checks for divisibility of each number less than it.

Ruby, 21 + 1 = 22 19 + 1 = 20 bytes
Also throwing my hat into the Ruby battle using the regex approach (and improved using histocrat's suggestion):
p !/^(11+)\1+$|^1$/

Takes input as a unary string and invoked using the n flag:
$ ruby -ne 'p !/^(11+)\1+$|^1$/' <<< 11111
true

Ooh, you can drop two in fact. p !/^(11+)\1+$|^1$/

@histocrat Interesting. I didn't know about that. However, it gives me warning: regex literal in condition. Since the rules state "if possible, output should consist solely of the string representation of a truthy or falsy value," I'd need to add the W0 flag, so it's a wash. Thanks for the tip, though.

@histocrat A-ha, it only gives that warning when I run it from a file rather than as a one-liner. So thank you indeed for that.

O, 23 bytes
j.1>\J2/{Jn%0={0}{}?}dp

Take 2! This one uses trial by division.

Python 2, 46 65 52 51 bytes

Went up to 65 bytes - Fix made thanks to feersum & Mauris
Went down to 52 bytes - Suggestions made by kirbyfan64sos and accepts in input from STDIN to complete the code.
Went down to 51 bytes - Suggestion made by kirbyfan64sos (thanks again!) to remove the space between 1 and and.  Apparently if you have a letter that follows a number, a space isn't needed... how weird, but cool!

This finds the remainder / modulus of the input integer n divided by every number from 2 up to n-1.  If there is at least one number in this sequence that has no remainder, or results in 0, this means that the number is not prime.  If every value in this sequence is non-zero, the value is prime.  Also by definition, 1 isn't prime and so that has to be taken care of separately.
n=input();print n!=1and all(n%i for i in range(2,n))

Example Runs
I ran this in IPython:
In [10]: n=input();print n!=1and all(n%i for i in range(2,n))
1
False

In [11]: n=input();print n!=1and all(n%i for i in range(2,n))
2
True

In [12]: n=input();print n!=1and all(n%i for i in range(2,n))
3
True

In [13]: n=input();print n!=1and all(n%i for i in range(2,n))
4
False

In [14]: n=input();print n!=1and all(n%i for i in range(2,n))
5
True

In [15]: n=input();print n!=1and all(n%i for i in range(2,n))
6
False

In [16]: n=input();print n!=1and all(n%i for i in range(2,n))
7
True

In [17]: n=input();print n!=1and all(n%i for i in range(2,n))
10
False

In [18]: n=input();print n!=1and all(n%i for i in range(2,n))
15
False

In [19]: n=input();print n!=1and all(n%i for i in range(2,n))
17
True

In [20]: n=input();print n!=1and all(n%i for i in range(2,n))
20
False

In [21]: n=input();print n!=1and all(n%i for i in range(2,n))
30
False

It has to return false for 1.

You made it return False for every possible input but 1, which should be False :)

@Mauris - Oops.   I didn't fix that properly lol.  Was on mobile.  I'm on my computer now. Fixing.

@Mauris - Fixed now.  Thanks.

@feersum - Now officially fixed. Thanks.

I think you can reduce this to def f(n):print(n==1 and all(n%i for i in range(2,n))) (but I haven't tested it).

@kirbyfan64sos - Let me experiment.  Thanks for the tips.

@kirbyfan64sos - Nope.  Same problem as before.  Returns True for n==1 and False otherwise.

Try def f(n):print n!=1 and all(n%i for i in range(2,n)). It needs to be a complete program, though.

@kirbyfan64sos - OK, made it a full program.  Went up to 52 bytes.  Thanks for the tips!

@rayryeng One more change: you can shave 2 or 3 bytes by dropping the parentheses for the print call and removing the space before the or thanks to Python's weird parser: n=input();print n==1or all(n%i for in range(2,n)).

@kirbyfan64sos - really?  Wow I never knew that about the or.  Thanks for the tips again! BTW, I went with your second attempt.  The first attempt that I did to change the and to or is wrong.

@rayryeng Yeah, I didn't know about it either until around a month ago! Apparently, any time a keyword immediately follows a number, you can leave out the space.

@kirbyfan64sos - Wicked.  Thanks so much!  BTW, I +1ed your O attempt.  Nice and sweet!

Wow, this is almost the  exact same code I wrote :) You can save a char by using > instead of !=.

C, 61 bytes
r;main(i,j){r=(--i>1);for(j=i-1;j>1;)r*=!!(i%j--);return r;}

Uses unary representation - the number is encoded in the number of commandline arguments. The return value is initialized to 1 and then, it's multiplied by the sign of remainder of division of the tested number and numbers 2..i-1 in a loop. So it will be zeroed when any non-trivial divisor found.
The result is returned to the system as the exit code.
Test:
echo 'r;main(i,j){r=(--i>1);for(j=i-1;j>1;)r*=!!(i%j--);return r;}' > main.c
gcc -o main main.c
./main 1 ; echo $?
./main 1 1 ; echo $?
./main 1 1 1 ; echo $?
./main 1 1 1 1 ; echo $?
./main 1 1 1 1 1 ; echo $?
./main 1 1 1 1 1 1 ; echo $?
./main 1 1 1 1 1 1 1 ; echo $?
./main 1 1 1 1 1 1 1 1 ; echo $?
./main 1 1 1 1 1 1 1 1 1 ; echo $?
./main 1 1 1 1 1 1 1 1 1 1 ; echo $?
./main 1 1 1 1 1 1 1 1 1 1 1 ; echo $?

Bash+coreutils, 29 bytes
echo $[`factor $1|wc -w`==2]

Test:
echo 'echo $[`factor $1|wc -w`==2]' > primetest.sh
chmod +x primetest.sh
./primetest.sh <NUMBER_TO_TEST>

Fortran 90, 66 55 bytes
Using trial division.
read*,i
do1 j=2,i
1 if(mod(i,j)==0)exit
print*,i==j
end

Saved 11 bytes thanks to sigma.
A do loop with labelled statement (not an enddo or continue) is still valid in Fortran 90, but obsolete.
Alternative using Wilson's theorem (56 bytes):
read*,j
k=1
do1 i=2,j-1
1 k=mod(k*i,j)
print*,k==j-1
end

Aww you beat me, now I'll have to come up with a different Fortran solution! Some tips though: the program statement is not necessary, which will save you 9 bytes, and you can also get away with writing do1 instead of do 1.

C#, 156 133 130 bytes
(second attempt after the first didn't exactly work)
using System;class C{static void Main(string[]a){int i=2,n=int.Parse(a[0]),b=n-1;for(;i<=n/2;)b*=n%i++>0?1:0;Console.Write(b>0);}}

(and thanks to Dennis for helping me out with my first code golf :) )

Welcome to Programming Puzzles & Code Golf! In its current form, your answer simply prints the result of the last divisibility test. You can fix that by initializing b=1 and multiplying b by the results (b*=...).

I'm not a C# expert, but since C# doesn't have implicit int-to-bool conversion, I don't think 1/0 satisfy the definition of truthy/falsy. using System;class C{static void Main(string[] a){int i=2,n=Int32.Parse(a[0]),b=n-1;for(;i<=n/2;)b*=n%i++>0?1:0;Console.Write(b>0);}} produces the proper output (and is 23 bytes shorter).

Ah, I see. I would have said that 1/0 does satisfy the condition, but I'll stick with your definition. :)

For most languages, it does. However, our definition counts 1 as truthy if if(1){...} executes the block, which doesn't seem to wok in C# (again, not an expert).

You can remove the space between string[] and a. Also, you can change Int32 to just int.

Like the Java answer, you can save a few bytes by changing the loop condition to i<n.  Although in practice the code i<=n/2 runs faster, the code for this question only has to work, not be fast.  Besides, either way, the algorithm isn't very efficient.

Smalltalk, 47 characters
Obviously no competition for isPrime if the Smalltalk dialect has it, but not all do. For example, the one used in Coding Ground (GNU Smalltalk v3.2.5) does not have it.
I'm relying on the observation that GCD((n - 1)!, n) = 1 for prime n which I haven't seen used very often. Ridiculously bad algorithm, but Smalltalk has no problem working with large integers. Replace the 2 with whatever you want to test:
|n|n:=2.((n>1)&((n-1)factorial gcd:n)=1)inspect

It does not consider 1 as prime as required by the OP. However, one widely accepted definition of a prime number is a natural number greater than 1 that has no positive divisors other than 1 and itself. So by this definition, 1 shouldn't be a candidate for primality testing, any more than 0, ½, i, e or π should be.
Note that in some situations, -1 is considered prime, because -1 = 1 × -1, and is used as such in some factorization algorithms.

J, 4 bytes
1&p:

This is essentially a built-in function for J as p: provides several different prime-related functions, depending on the left argument (attached here with 1&).
As with J in general, it is incredibly array-friendly:
   1&p: 0 1 2 3 4 5 6 7 8 9 10
0 0 1 1 0 1 0 1 0 0 0

Perl, 25 bytes
#!perl -p
$_=2==grep$'%$_<1,//..$_

Counting the shebang as one. Input is taken, in decimal, from stdin.
Sample Usage:
$ echo 101101 | perl isprime.pl

$ echo 101107 | perl isprime.pl
1

Perl, 24 bytes
#!perl -p
$_=3>grep$'%$_<1,//..$_

One byte can be shaved by replacing 2== with 3>, however, it will incorrectly identify both 0 and 1 as prime.

Scratch, 17 blocks (currently glitchy)
demo

Self-explanatory...
Edit: I fixed 2 bugs. But, if you enter 1, it gets in an infinite loop...

I tried the demo, and entering 7 returns False?

@mathmandan: Yeah, there were 2 bugs. I'll fix them, but the block count will be the same.

This seems to loop forever for input 1.

@Dennis: Noted. Will fix with 5 more blocks

As before: Scratch is typically scored by the number of bytes in the corresponding scratchblocks code here.

Ouroboros, 39 bytes
Sr0s1(
)S1+.@@.@@%!Ms+S.@@.@>6*(6s2=n1(

Each line of code in an Ouroboros program represents a snake eating its tail.
Snake 1
S switches to the shared stack; r0 reads a number from input and pushes a 0. Then s1( switches back to snake 1's stack, pushes a 1, and eats that many characters of the tail. The instruction pointer is on a character that gets eaten, so the snake dies.
Snake 2
Here the magic happens. We check every number from 1 up through n, adding 1 to a tally if it divides our input number. At the end we check whether the number of factors equals 2 and print 1 or 0 accordingly.
) is a no-op the first time through. S switches to the shared stack. We then push a 1 (just after the first snake pushes its 0) and add. The stack now contains the input number and the factor we're testing for divisibility.
.@@.@@%! makes copies of both numbers, takes the modulus, and negates (1 if it is a factor, 0 if not). M moves that result to snake 2's stack, where we're storing the tally of factors; then s+S switches to that stack, adds the top two numbers, and switches back to the shared stack.
Next, .@@.@>6* makes copies of both numbers and tests whether the input number is greater than the test factor, pushing 6 if so and 0 if not. ( then eats that many characters from the end of the snake.

If the number is still greater than the factor, the uneaten code now ends after (6. This pushes a 6 and wraps execution back to the beginning. There ) regurgitates the 6 characters we just ate. S does nothing because we're already on the shared stack. 1+ then increments the test factor, and we go through the loop again.
When the number is no longer greater than the factor, nothing gets eaten and execution continues. We push a 6 but then switch to snake 2's stack, where the number of factors is sitting. 2=n tests whether it's 2 and outputs the result (1 or 0) as a number. Finally, 1( eats the last character and dies.

Try it out

// Define Stack class
function Stack() {
  this.stack = [];
  this.length = 0;
}
Stack.prototype.push = function(item) {
  this.stack.push(item);
  this.length++;
}
Stack.prototype.pop = function() {
  var result = 0;
  if (this.length > 0) {
    result = this.stack.pop();
    this.length--;
  }
  return result;
}
Stack.prototype.top = function() {
  var result = 0;
  if (this.length > 0) {
    result = this.stack[this.length - 1];
  }
  return result;
}
Stack.prototype.toString = function() {
  return "" + this.stack;
}

// Define Snake class
function Snake(code) {
  this.code = code;
  this.length = this.code.length;
  this.ip = 0;
  this.ownStack = new Stack();
  this.currStack = this.ownStack;
  this.alive = true;
  this.wait = 0;
  this.partialString = this.partialNumber = null;
}
Snake.prototype.step = function() {
  if (!this.alive) {
    return null;
  }
  if (this.wait > 0) {
    this.wait--;
    return null;
  }
  var instruction = this.code.charAt(this.ip);
  var output = null;
  console.log("Executing instruction " + instruction);
  if (this.partialString !== null) {
    // We're in the middle of a double-quoted string
    if (instruction == '"') {
      // Close the string and push its character codes in reverse order
      for (var i = this.partialString.length - 1; i >= 0; i--) {
        this.currStack.push(this.partialString.charCodeAt(i));
      }
      this.partialString = null;
    } else {
      this.partialString += instruction;
    }
  } else if (instruction == '"') {
    this.partialString = "";
  } else if ("0" <= instruction && instruction <= "9") {
    if (this.partialNumber !== null) {
      this.partialNumber = this.partialNumber + instruction;  // NB: concatenation!
    } else {
      this.partialNumber = instruction;
    }
    next = this.code.charAt((this.ip + 1) % this.length);
    if (next < "0" || "9" < next) {
      // Next instruction is non-numeric, so end number and push it
      this.currStack.push(+this.partialNumber);
      this.partialNumber = null;
    }
  } else if ("a" <= instruction && instruction <= "f") {
    // a-f push numbers 10 through 15
    var value = instruction.charCodeAt(0) - 87;
    this.currStack.push(value);
  } else if (instruction == "$") {
    // Toggle the current stack
    if (this.currStack === this.ownStack) {
      this.currStack = this.program.sharedStack;
    } else {
      this.currStack = this.ownStack;
    }
  } else if (instruction == "s") {
    this.currStack = this.ownStack;
  } else if (instruction == "S") {
    this.currStack = this.program.sharedStack;
  } else if (instruction == "l") {
    this.currStack.push(this.ownStack.length);
  } else if (instruction == "L") {
    this.currStack.push(this.program.sharedStack.length);
  } else if (instruction == ".") {
    var item = this.currStack.pop();
    this.currStack.push(item);
    this.currStack.push(item);
  } else if (instruction == "m") {
    var item = this.ownStack.pop();
    this.program.sharedStack.push(item);
  } else if (instruction == "M") {
    var item = this.program.sharedStack.pop();
    this.ownStack.push(item);
  } else if (instruction == "y") {
    var item = this.ownStack.top();
    this.program.sharedStack.push(item);
  } else if (instruction == "Y") {
    var item = this.program.sharedStack.top();
    this.ownStack.push(item);
  } else if (instruction == "\\") {
    var top = this.currStack.pop();
    var next = this.currStack.pop()
    this.currStack.push(top);
    this.currStack.push(next);
  } else if (instruction == "@") {
    var c = this.currStack.pop();
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(c);
    this.currStack.push(a);
    this.currStack.push(b);
  } else if (instruction == ";") {
    this.currStack.pop();
  } else if (instruction == "+") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(a + b);
  } else if (instruction == "-") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(a - b);
  } else if (instruction == "*") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(a * b);
  } else if (instruction == "/") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(a / b);
  } else if (instruction == "%") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(a % b);
  } else if (instruction == "_") {
    this.currStack.push(-this.currStack.pop());
  } else if (instruction == "I") {
    var value = this.currStack.pop();
    if (value < 0) {
      this.currStack.push(Math.ceil(value));
    } else {
      this.currStack.push(Math.floor(value));
    }
  } else if (instruction == ">") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(+(a > b));
  } else if (instruction == "<") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(+(a < b));
  } else if (instruction == "=") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(+(a == b));
  } else if (instruction == "!") {
    this.currStack.push(+ !this.currStack.pop());
  } else if (instruction == "?") {
    this.currStack.push(Math.random());
  } else if (instruction == "n") {
    output = "" + this.currStack.pop();
  } else if (instruction == "o") {
    output = String.fromCharCode(this.currStack.pop());
  } else if (instruction == "r") {
    var input = this.program.io.getNumber();
    this.currStack.push(input);
  } else if (instruction == "i") {
    var input = this.program.io.getChar();
    this.currStack.push(input);
  } else if (instruction == "(") {
    this.length -= Math.floor(this.currStack.pop());
    this.length = Math.max(this.length, 0);
  } else if (instruction == ")") {
    this.length += Math.floor(this.currStack.pop());
    this.length = Math.min(this.length, this.code.length);
  } else if (instruction == "w") {
    this.wait = this.currStack.pop();
  }
  // Any unrecognized character is a no-op
  if (this.ip >= this.length) {
    // We've swallowed the IP, so this snake dies
    this.alive = false;
    this.program.snakesLiving--;
  } else {
    // Increment IP and loop if appropriate
    this.ip = (this.ip + 1) % this.length;
  }
  return output;
}
Snake.prototype.getHighlightedCode = function() {
  var result = "";
  for (var i = 0; i < this.code.length; i++) {
    if (i == this.length) {
      result += '';
    }
    if (i == this.ip) {
      if (this.wait > 0) {
        result += '';
      } else {
        result += '';
      }
      result += escapeEntities(this.code.charAt(i)) + '';
    } else {
      result += escapeEntities(this.code.charAt(i));
    }
  }
  if (this.length < this.code.length) {
    result += '';
  }
  return result;
}

// Define Program class
function Program(source, speed, io) {
  this.sharedStack = new Stack();
  this.snakes = source.split(/\r?\n/).map(function(snakeCode) {
    var snake = new Snake(snakeCode);
    snake.program = this;
    snake.sharedStack = this.sharedStack;
    return snake;
  }.bind(this));
  this.snakesLiving = this.snakes.length;
  this.io = io;
  this.speed = speed || 10;
  this.halting = false;
}
Program.prototype.run = function() {
  this.step();
  if (this.snakesLiving) {
    this.timeout = window.setTimeout(this.run.bind(this), 1000 / this.speed);
  }
}
Program.prototype.step = function() {
   for (var s = 0; s < this.snakes.length; s++) {
    var output = this.snakes[s].step();
    if (output) {
      this.io.print(output);
    }
  }
  this.io.displaySource(this.snakes.map(function (snake) {
      return snake.getHighlightedCode();
    }).join("
"));
 }
Program.prototype.halt = function() {
  window.clearTimeout(this.timeout);
}

var ioFunctions = {
  print: function (item) {
    var stdout = document.getElementById('stdout');
    stdout.value += "" + item;
  },
  getChar: function () {
    if (inputData) {
      var inputChar = inputData[0];
      inputData = inputData.slice(1);
      result = inputChar.charCodeAt(0);
    } else {
      result = -1;
    }
    var stdinDisplay = document.getElementById('stdin-display');
    stdinDisplay.innerHTML = escapeEntities(inputData);
    return result;
  },
  getNumber: function () {
    while (inputData && (inputData[0] < "0" || "9" < inputData[0])) {
      inputData = inputData.slice(1);
    }
    if (inputData) {
      var inputNumber = inputData.match(/\d+/)[0];
      inputData = inputData.slice(inputNumber.length);
      result = +inputNumber;
    } else {
      result = -1;
    }
    var stdinDisplay = document.getElementById('stdin-display');
    stdinDisplay.innerHTML = escapeEntities(inputData);
    return result;
  },
  displaySource: function (formattedCode) {
    var sourceDisplay = document.getElementById('source-display');
    sourceDisplay.innerHTML = formattedCode;
  }
};
var program = null;
var inputData = null;
function showEditor() {
  var source = document.getElementById('source'),
    sourceDisplayWrapper = document.getElementById('source-display-wrapper'),
    stdin = document.getElementById('stdin'),
    stdinDisplayWrapper = document.getElementById('stdin-display-wrapper');

  source.style.display = "block";
  stdin.style.display = "block";
  sourceDisplayWrapper.style.display = "none";
  stdinDisplayWrapper.style.display = "none";

  source.focus();
}
function hideEditor() {
  var source = document.getElementById('source'),
    sourceDisplay = document.getElementById('source-display'),
    sourceDisplayWrapper = document.getElementById('source-display-wrapper'),
    stdin = document.getElementById('stdin'),
    stdinDisplay = document.getElementById('stdin-display'),
    stdinDisplayWrapper = document.getElementById('stdin-display-wrapper');

  source.style.display = "none";
  stdin.style.display = "none";
  sourceDisplayWrapper.style.display = "block";
  stdinDisplayWrapper.style.display = "block";

  var sourceHeight = getComputedStyle(source).height,
    stdinHeight = getComputedStyle(stdin).height;
  sourceDisplayWrapper.style.minHeight = sourceHeight;
  sourceDisplayWrapper.style.maxHeight = sourceHeight;
  stdinDisplayWrapper.style.minHeight = stdinHeight;
  stdinDisplayWrapper.style.maxHeight = stdinHeight;
  sourceDisplay.textContent = source.value;
  stdinDisplay.textContent = stdin.value;
}
function escapeEntities(input) {
  return input.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
}
function resetProgram() {
  var stdout = document.getElementById('stdout');
  stdout.value = null;
  if (program !== null) {
    program.halt();
  }
  program = null;
  inputData = null;
  showEditor();
}
function initProgram() {
  var source = document.getElementById('source'),
    stepsPerSecond = document.getElementById('steps-per-second'),
    stdin = document.getElementById('stdin');
  program = new Program(source.value, +stepsPerSecond.innerHTML, ioFunctions);
  hideEditor();
  inputData = stdin.value;
}
function runBtnClick() {
  if (program === null || program.snakesLiving == 0) {
    resetProgram();
    initProgram();
  } else {
    program.halt();
    var stepsPerSecond = document.getElementById('steps-per-second');
    program.speed = +stepsPerSecond.innerHTML;
  }
  program.run();
}
function stepBtnClick() {
  if (program === null) {
    initProgram();
  } else {
    program.halt();
  }
  program.step();
}
function sourceDisplayClick() {
  resetProgram();
}
.container {
    width: 100%;
}
.so-box {
    font-family:'Helvetica Neue', Arial, sans-serif;
    font-weight: bold;
    color: #fff;
    text-align: center;
    padding: .3em .7em;
    font-size: 1em;
    line-height: 1.1;
    border: 1px solid #c47b07;
    -webkit-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.3), 0 2px 0 rgba(255, 255, 255, 0.15) inset;
    text-shadow: 0 0 2px rgba(0, 0, 0, 0.5);
    background: #f88912;
    box-shadow: 0 2px 2px rgba(0, 0, 0, 0.3), 0 2px 0 rgba(255, 255, 255, 0.15) inset;
}
.control {
    display: inline-block;
    border-radius: 6px;
    float: left;
    margin-right: 25px;
    cursor: pointer;
}
.option {
    padding: 10px 20px;
    margin-right: 25px;
    float: left;
}
h1 {
    text-align: center;
    font-family: Georgia, 'Times New Roman', serif;
}
a {
    text-decoration: none;
}
input, textarea {
    box-sizing: border-box;
}
textarea {
    display: block;
    white-space: pre;
    overflow: auto;
    height: 50px;
    width: 100%;
    max-width: 100%;
    min-height: 25px;
}
span[contenteditable] {
    padding: 2px 6px;
    background: #cc7801;
    color: #fff;
}
#stdout-container, #stdin-container {
    height: auto;
    padding: 6px 0;
}
#reset {
    float: right;
}
#source-display-wrapper , #stdin-display-wrapper{
    display: none;
    width: 100%;
    height: 100%;
    overflow: auto;
    border: 1px solid black;
    box-sizing: border-box;
}
#source-display , #stdin-display{
    font-family: monospace;
    white-space: pre;
    padding: 2px;
}
.activeToken {
    background: #f93;
}
.nextActiveToken {
    background: #bbb;
}
.swallowedCode{
    color: #999;
}
.clearfix:after {
    content:".";
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
}
.clearfix {
    display: inline-block;
}
* html .clearfix {
    height: 1%;
}
.clearfix {
    display: block;
}

<textarea id="source" placeholder="Enter your program here" wrap="off">Sr0s1(
)S1+.@@.@@%!Ms+S.@@.@>6*(6s2=n1(</textarea>

<textarea id="stdin" placeholder="Input" wrap="off">5</textarea>

<input type="button" id="run" class="control so-box" value="Run" onclick="runBtnClick()" /><input type="button" id="pause" class="control so-box" value="Pause" onclick="program.halt()" /><input type="button" id="step" class="control so-box" value="Step" onclick="stepBtnClick()" /><input type="button" id="reset" class="control so-box" value="Reset" onclick="resetProgram()" />

<textarea id="stdout" placeholder="Output" wrap="off" readonly></textarea>

Steps per Second:
20

Vitsy, 2 bytes
Yes, it's that Simple...x.
pN
   Implicit grab of STDIN as number, if possible.
p  If it's prime, push 1 to the stack. Else, push 0.
 N Output as number.

Interestingly, adding an i to this will also find prime characters.
ipN
For input % (ASCII character 37) will output 1.

Haha, so punny! +1 from me.

Arcyóu, 42 7 bytes
Note: I added a builtin for primality testing after I submitted this answer. In the interest of completeness, I have left the old answer below, but this is the new official answer:
(p?(#(l

Primality check on a line of input casted to int.

Old answer:
((F(n)(?([ n)(&(f x(_ 2 n)(% n x)))f))(#(l

Arcyóu is a LISP-like golfing language of my own devising.
Explanation:
((F(n)               ; Anonymous function taking one argument n
  (? ([ n)           ; If-statement with condition n-1 (handling the special case)
    (&               ; & is both bitwise AND and an 'all' function
      (f x (_ 2 n)   ; For loop iterating over a range from 2 to n
        (% n x)))    ; n mod x
    f))              ; If n did equal 1, return false
(# (l                ; Now call the function on a line of input casted to int

The interpreter allows you to leave off final close-parens, since adding them back is trivial.

, 3 chars / 6 bytes
МȜï

Try it here (Firefox only).
Not sure why I didn't post this earlier...
Bonus solution, 5 chars / 10 bytes
!МȝïꝈ

Try it here (Firefox only).
Checks if the input's array of prime factorization is greater than 0.

Jelly, 4 bytes
’!²%

Try it online!
Jelly has a built-in for primality testing (ÆP, 2 bytes), but it uses a probabilistic method.
This answer uses Wilson's theorem instead. For input x, it calculates (x - 1)!² % x, which yields 1 if x is a prime number and 0 if not.
        Input: x

’       Decrement; compute x - 1.
 !      Apply factorial atop the previous result. Yields (x - 1)!.
  ²     Apply square atop the previous result. Yields (x - 1)!².
   %    Do a modulus hook; compute (x - 1)!² % x.

Par, 9 bytes
Counted using its own, non-UTF-8 encoding.
✶↓″↑p~1=*

Explanation:
✶          Parse the input (which is
             implicitly on the stack).    n
 ↓         Subtract one.                  (n-1)
  ″        Duplicate.                     (n-1)  (n-1)
   ↑       Add one.                       (n-1)  n
    p      Prime divisors. For 1, this
             strangely returns (1).       (n-1)  np
     ~     Length.                        (n-1)  np~
      1=   Is the length one? This is
             iff n isn't composite.       (n-1)  noncomposite(n)
        *  Multiply the top of stack.     (n-1)*noncomposite(n)

Binary-Encoded Golfical, 13+1 (-x flag) = 14 bytes
This can converted to the standard graphical version using the included Encoder utility, or run directly by adding the -x flag.
Hex dump:
00 40 02 15 14 49 1b 00 00 00 01 17 17

The original image:

Zoomed in 100x with color value lables:

Explanation:
10,0,0->Input number
14,3,0->Turn right if prime
11,0,1->Go east
0,0,0->Set to 0
0,0,1->Set to 1
10,1,0->Print number

MediaWiki templates with ParserFunctions, 101 + 1 = 102 bytes (for title)
{{#ifexpr:{{{n}}} mod {{{f|(n-1)}}}==0|false|{{#ifexpr:{{{f}}}==1|true|{{:p|n=n|f={{#expr:f-1}}}}}}}}

Ungolfed:
{{#ifexpr:{{{n}}} mod {{{f|(n-1)}}}==0|false|
    {{#ifexpr:{{{f}}}==1|true|
        {{p|n=n|f={{#expr:f-1}}}}
    }}
}}

This recursive trial division method theoretically works, but to determine the primality of a positive integer n, $wgMaxTemplateDepth (in the MediaWiki config) must exceed n - 2.

So, in practice, this works for no single input? According to the rules, it must work at least for integers 1 to 255...

This solution is valid for wikis that allow at least a recursive depth of 253.

Samau, 2 bytes
▌τ

Hex dump:
dd ab

Yes, it's 2 bytes. Samau uses CP737 as its default character encoding.
▌       read a number
 τ      test if it is a prime

τ uses the isCertifiedPrime function in the haskell package arithmoi. It's not a probabilistic algorithm.

There's also a 7-bytes answer if built-ins are not allowed:
▌;\│Σ2=

Hex dump:
dd 3b 5c b3 91 32 3d

Most mathematical functions in Samau automatically thread over lists.
▌           read a number, let's call it n
 ;          duplicate
  \         range from 1 to n
   |        return 1 for divisors of n, and 0 for the other numbers
    Σ       take the sum
     =2     if the sum is 2, then it's a prime

Befunge 93, 44 bytes
&:v>0.@       @.-1<
03<_v#%p03+1:g03::_^#`g

This works by trial division.
There's a hidden unprintable character between the v> on the first line; it's the character whose value is 2. The base64 of the file is as follows:
Jjp2Aj4wLkAgICAgICAgQC4tMTwKMDM8X3YjJXAwMysxOmcwMzo6X14jYGc=

Opening it as hex in Sublime Text looks like this (newline confusion, though):
263a 7602 3e30 2e40 2020 2020 2020 2040
2e2d 313c 0d0a 3033 3c5f 7623 2570 3033
2b31 3a67 3033 3a3a 5f5e 2360 670d 0a

Try this out here.

JavaScript (ES6), 54 bytes
for((x=prompt(a=i=1))>1||a--;++i<x;x%i?0:a=0);alert(a)

Outputs 1 for prime, 0 for non-prime. All four JS solutions so far were based on the regex, so I thought I'd be brave and try one without.

MATL, 2 bytes
Zp

Try it online!
Takes input implicitly. For positive input, function Zp outputs true (displayed as 1) if the number is prime, ans false (0)  otherwise.

Turtlèd, 490 487 451 bytes
Turtlèd does not support newlines in code... so oneliner fun!
golfed some bytes for not needing to support 0
Golfed some bytes removing useless code, and some other tricks
?#0#.:l( >;,u,[ :ll[*,l]d],u{*{*r}l' d{ l}[ (*.d)(0'1d)(1'2d)(2'3d)(3'4d)(4'5d)(5'6d)(6'7d)(7'8d)(8'9d)(9.l( .))]u[ r]lu}u2[#[ ;{ l}[ (0u.)(1u'1)(2u'2)(3u'3)(4u'4)(5u'5)(6u'6)(7u'7)(8u'8)(9u'9)dl]ur[ r]l[#[ r]l[ (0'9l( '#;))(1.;)(2'1;)(3'2;)(4'3;)(5'4;)(6'5;)(7'6;)(8'7;)(9'8;)]uuu[*r]{*l}u{*r}'*{*l}:;{ l}[ l]r]' uu[*r]{*r}d]l(*,(*@1)(1@0)'*)u{*' l}:;d[ (0'9l( '#l))(1.d)(2'1d)(3'2d)(4'3d)(5'4d)(6'5d)(7'6d)(8'7d)(9'8d)]r( u[ r]uu)][ [ l]r[ ' r]ul],)

Try it online!
I am most certainly not going to explain this with the annotations for each part of the code, at least not right now.
General explanation:
The program writes 0, takes integer input, if it is not one (if it is, it skips the rest of the code), it writes out two lines of asterisks, removing the zero that was written, one to compare for the prime checking, one to turn into a decimal string. It turns the lower one into a decimal string, then moves the decimal string up one. It writes out a single asterisk into a line above the other for each decrement of the upper decimal string. when goes below zero, the program moves the decimal string back up again, and keeps going on the upper line until it either aligns with the lower line, or goes past it. If it aligns, it sets the character variable to 1, if the character variable has not already been set to one. This is because it has no method to distinguish one when testing divisibility, so this makes it so it has to have more than one factor match. If it has been set to one, it sets it to zero. After it has tested all the numbers from n-1 to 1, it cleans up all the mess that it used to test the primality, then writes the character variable, which will be one if prime, else 0

Input 1 seems to result in an infinite loop.

@Dennis Fixed!!

@ConorO'Brien Submissions must terminate by default.

@Dennis oh ok then

I'm fairly sure I can golf some bytes, but the code is too.... ehhhh. It bugged out when I tried

Haskell, 47 52 bytes
main=do n<-readLn;print$n>1&&all((>0).mod n)[2..n-1]

EDIT: I had failed to take 1 into account. Fixed!

Welcome to ppcg! Nice first post! Congrats on out-golfing the other existing haskell answers!

This code returns True for 1 which is not valid according to the specification.

Alice, 12 11 bytes
/o|\ntdc
@i

Try it online!
Prints 1 for primes and 0 for composite numbers and 1. Here is an alternative solution that prints p-1 for primes instead:
/o|\tzt.
@i

Try it online!
Explanation
/   Send the IP southeast, switching to Ordinal mode.
i   Read all input as a string.
|   Reflect the IP back where it came from.
i   Try reading input again, but this just pushes "".
/   Send the IP west, switching back to Cardinal mode.
    The IP wraps around to the end of the line.
c   Convert the input to an integer and push its prime factors. Pushes nothing
    at all for input 1.
d   Get the stack depth. This is 1 iff the input is a prime.
t   Decrement to give 0 for primes.
n   Logical NOT. Now we have 1 for primes, 0 otherwise.
\   Send the IP southwest, switching to Ordinal mode.
o   Print the result as a string.
@   Terminate the program.

q, 35 34 bytes
Haven't golfed much yet, but we can drop 2 bytes easily if we're allowed to return nothing for 1 and 2. Really, the language truly shines in code golf where the seemingly golfed code is just idiomatic q. Using q instead of k lets us use min, mod and til operators to save some bytes.
Having to read STDIN isn't much idiomatic q, and costed us 11 bytes.
-> I was able to save a byte due to on-the-fly assignments which I forgot about
0>min 1,x mod/:2_til x:"I"$read0 0

Explanation
code is executed right-to-left
"I"$read0 0 reads STDIN, and then casts it to an integer
{..} denotes an anonymous function with x as an implicit variable, applied to the integer
til x returns a range 0..(x-1)
2_ drops 0 and 1, which are not needed for prime checking
1,x mod/: then takes mod of x with every element of the list and prepends a 1 to the list due to 1 and 2 returning empty list
0<min takes the minimum of the mods, and checks if it is bigger than zero. If it is, then it must be a prime!

Welcome to PPCG!

Whitespace, 145 137 134 bytes
[S S S N
_Push_0][S N
S _Duplicate][T N
T   T   _Read_STDIN_as_integer_in_heap_0][T T   T   _Retrieve][S S S T  S N
_Push_2][T  S S T   _Subtract][N
T   T   T   T   N
_Jump_to_Label_FALSE_if_negative][S S S T   N
_Push_1][S N
S _Duplicate_1][N
S S N
_Create_Label_LOOP][S N
N
_Discard_top_stack][S S S T N
_Push_1][T  S S S _Add][S N
S _Duplicate][S N
S _Duplicate][S S S N
_Push_0][T  T   T   _Retrieve_heap_at_0][T  S S T   _subtract][N
T   S T N
_Jump_to_Label_TRUE_if_0][S S S N
_Push_0][T  T   T   _Retrieve_heap_0][S N
T   _Swap_top_two][T    S T T   _Modulo][S N
S _Duplicate][N
T   S T T   N
_Jump_to_Label_FALSE_if_0][N
S N
N
_Jump_to_Label_LOOP][N
S S T   N
_Create_Label_TRUE][S S S T N
_Push_1][T  N
S T _Output_1][N
N
N
_Exit][N
S S T   T   N
_Create_Label_FALSE][S S S N
_Push_0][T  N
S T _Output_0]

Letters S (space), T (tab), and N (new-line) added as highlighting only.
[..._some_action] added as explanation only.
Outputs 1 if a prime, 0 otherwise.
Try it online (with raw spaces, tabs, and new-lines only).
General explanation:

Read input
Is it less than 2: Return 0
Integer i=1
Start loop

5) Increase i by 1
6) If the input and i are equal: Return 1 (last iteration of the loop)
7a) Is the input modulo i 0: Return 0
7b) Else: Go back to step 5

Example run (with 5 as input):
Command   Explanation                   Stack       Heap    STDIN   STDOUT

SSSN      Push 0                        [0]         {}
SNS       Duplicate (0)                 [0,0]       {}
TNTT      Read STDIN as number          [0]         {0:5}   5
TTT       Retrieve heap at 0            [5]         {0:5}
SSSTSN    Push 2                        [5,2]       {0:5}
TSST      Subtract (5-2)                [3]         {0:5}
NTTTTN    Jump to Label_FALSE if neg.   []          {0:5}
SSSTN     Push 1                        [1]         {0:5}
SNS       Duplicate (1)                 [1,1]       {0:5}
NSSN      Create Label_LOOP             [1,1]       {0:5}
 SNN      Discard top                   [1]         {0:5}
 SSSTN    Push 1                        [1,1]       {0:5}
 TSSS     Add (1+1)                     [2]         {0:5}
 SNS      Duplicate (2)                 [2,2]       {0:5}
 SNS      Duplicate (2)                 [2,2,2]     {0:5}
 SSSN     Push 0                        [2,2,2,0]   {0:5}
 TTT      Retrieve heap at 0            [2,2,2,5]   {0:5}
 TSST     Subtract (2-5)                [2,2,-3]    {0:5}
 NTSTN    Jump to LABEL_TRUE if 0       [2,2]       {0:5}
 SSSN     Push 0                        [2,2,0]     {0:5}
 TTT      Retrieve heap at 0            [2,2,5]     {0:5}
 SNT      Swap top two (2,5] -> 5,2])   [2,5,2]     {0:5}
 TSTT     Modulo (5%2)                  [2,1]       {0:5}
 SNS      Duplicate (1)                 [2,1,1]     {0:5}
 NTSTTN   Jump to Label_FALSE if 0      [2,1]       {0:5}
 NSNN     Jump to Label_LOOP            [2,1]       {0:5}

 SNN      Discard top                   [2]         {0:5}
 SSSTN    Push 1                        [2,1]       {0:5}
 TSSS     Add (2+1)                     [3]         {0:5}
 SNS      Duplicate (3)                 [3,3]       {0:5}
 SNS      Duplicate (3)                 [3,3,3]     {0:5}
 SSSN     Push 0                        [3,3,3,0]   {0:5}
 TTT      Retrieve heap at 0            [3,3,3,5]   {0:5}
 TSST     Subtract (3-5)                [3,3,-2]    {0:5}
 NTSTN    Jump to LABEL_TRUE if 0       [3,3]       {0:5}
 SSSN     Push 0                        [3,3,0]     {0:5}
 TTT      Retrieve heap at 0            [3,3,5]     {0:5}
 SNT      Swap top two (3,5] -> 5,3])   [3,5,3]     {0:5}
 TSTT     Modulo (5%3)                  [3,2]       {0:5}
 SNS      Duplicate (2)                 [3,2,2]     {0:5}
 NTSTTN   Jump to Label_FALSE if 0      [3,2]       {0:5}
 NSNN     Jump to Label_LOOP            [3,2]       {0:5}

 SNN      Discard top                   [3]         {0:5}
 SSSTN    Push 1                        [3,1]       {0:5}
 TSSS     Add (3+1)                     [4]         {0:5}
 SNS      Duplicate (4)                 [4,4]       {0:5}
 SNS      Duplicate (4)                 [4,4,4]     {0:5}
 SSSN     Push 0                        [4,4,4,0]   {0:5}
 TTT      Retrieve heap at 0            [4,4,4,5]   {0:5}
 TSST     Subtract (4-5)                [4,4,-1]    {0:5}
 NTSTN    Jump to LABEL_TRUE if 0       [4,4]       {0:5}
 SSSN     Push 0                        [4,4,0]     {0:5}
 TTT      Retrieve heap at 0            [4,4,5]     {0:5}
 SNT      Swap top two (4,5] -> 5,4])   [4,5,4]     {0:5}
 TSTT     Modulo (5%4)                  [4,1]       {0:5}
 SNS      Duplicate (1)                 [4,1,1]     {0:5}
 NTSTTN   Jump to Label_FALSE if 0      [4,1]       {0:5}
 NSNN     Jump to Label_LOOP            [4,1]       {0:5}

 SNN      Discard top                   [4]         {0:5}
 SSSTN    Push 1                        [4,1]       {0:5}
 TSSS     Add (4+1)                     [5]         {0:5}
 SNS      Duplicate (5)                 [5,5]       {0:5}
 SNS      Duplicate (5)                 [5,5,5]     {0:5}
 SSSN     Push 0                        [5,5,5,0]   {0:5}
 TTT      Retrieve heap at 0            [5,5,5,5]   {0:5}
 TSST     Subtract (5-5)                [5,5,0]     {0:5}
 NTSTN    Jump to LABEL_TRUE if 0       [5,5]       {0:5}

NSSTN     Create Label_TRUE             [5,5]       {0:5}
SSSTN     Push 1                        [5,5,1]     {0:5}
TNST      Output top as number          [5,5]       {0:5}          1
NNN       Stop program                  [5,5]       {0:5}

APL, 9 chars/bytes
2≡≢∪∨∘⍳⍨⎕

get the input
⎕

compute least common divisor between n and all integers from 1 to n
∨∘⍳⍨

count of unique values
≢∪

if it's exactly 2, then it's prime
2≡

https://tio.run/##AS4A0f9hcGwtZHlhbG9n///ijpXihpAy4omh4omi4oiq4oio4oiY4o2z4o2oMTI5N///

GHC 8.2.2, 716 bytes
{-#LANGUAGE FlexibleInstances,FunctionalDependencies,UndecidableInstances,CPP#-}
#define i instance
#define c class
data F
data T
data S n
data C x s
c A p q r|p q->r
i A F q F
i A T q q
c E p x y z|p x y->z
i E F x y y
i E T x y x
c G x y b|x y->b
i G x F T
i G F(S y)F
i G x y b=>G(S x)(S y)b
c M x y z|x y->z
i M x F x
i M F(S y)F
i M x y z=>M(S x)(S y)z
c D x y b|x y->b
i D x F T
i(G(S y)x p,M(S y)x z,D x z q,A p q b)=>D x(S y)b
c K f x y|f x->y
i D m n b=>K(S n)m b
c I f s n|f s->n
i I f F F
i(K f x b,I f s m,E b(S m)m n)=>I f(C x s)n
c R n s|n->s
i R F F
i R n s=>R(S n)(C(S n)s)
c Q m n b|m n->b
i Q F F T
i Q F(S y)F
i Q(S x)F F
i Q x y b=>Q(S x)(S y)b
c P n b|n->b
i(R n s,I(S n)s m,Q m(S(S F))b)=>P n b

Try it online!
This has got to be the most beautiful code I've ever written. It's a compile-time metaprogram that determines whether a type (represented Peano-style, where F is zero and S n is n's successor) is prime.
This works in GHC 8.2.2, the version TIO currently uses. It works locally in 8.8.3 as well. I have included the language extensions in the code, all except one—the TIO example linked above has MonoLocalBinds to suppress a warning. The program works just fine without them.

If (and only if) your language is unable to accept any kind of user input, you may hardcode the input in your program.
Output has to be written to STDOUT or closest alternative.

As far as I know, metaprograms like this have no means of I/O. With FunctionalDependencies, typeclasses can act much like functions, and in this way, the typeclass P is a "function" from natural numbers to booleans (T and F—yes, the same type represents zero, false, and the empty list). I believe this to be the closest alternative to the standard streams.
The test suite I provided covers numbers from one to twenty. Try changing any T to F or vice-versa, and the program will fail to compile.
I know there are improvements that can be made, and I'll be updating this answer soonish with them.

Arn, 13 12 10 7 bytes
“sƥNm(┤

Previous versions:
ï_C3<│ì♦3(

├¦&┼6k┐ÇŠq""

{•Õ╝_¸”b¦¤º!E

Try it!
Explained
Unpacked: !(1+fact-1)%.
I may add a builtin for checking primality, but until then I made use of Wilson's Theorem; that is,
$$((n - 1)! + 1)\mod n\equiv 0$$
will yield true iff n is a prime number.
!                   Boolean Not
    (               Begin expression
        1           Literal one
      +             Addition
        fact        factorial function
            _       Variable initialized to STDIN; implied
          -         Subtraction
            1       Literal one
    )               End expression
  %                 Modulo
    _               Implied

Thank goodness I finally fixed operator precedence.

Finally! You proved that Arn is a programming language.

Idea: Add stuff that translates to (( or (((.

I do plan on adding a lot more builtins the future, so for the sake of more space I probably won't do anything like that (at least for now). That is a good idea though, Arn's opinionated fix chaining can be very annoying at times :p

Unfortunately that would evaluate to !(( _.fact / (_ + 1)) % _!((_.(fact / _) + 1) % _).
curse you fix chains!

Although, that did reveal another bug in my interpreter (naturally). Guess it's time to fix it!

Whoops, I accidentally deleted my message, re-posting it here. "(n-1)! is basically n!/n. I don't know Arn, but does this work? !((.fact/+1)%"

What is going on with the permalink... 12 bytes: ├¦&┼6k┐ÇŠq"" (ungolfed !(1+(fact _/)%)

That's because there's an & in the encoded program... I'm still working on the bugs :p. Good job though!

ARM Thumb, no div instructions, 43 bytes
f7ff fffe represents placeholders for libc calls, to scanf and printf respectively.
b503 4669 a008 f7ff fffe bc03 2802 d907
2202 0001 1a89 d003 d8fc 3201 4282 d1f8
a001 f7ff fffe bd00 6425 00

Assembly code:
        .globl main
        .thumb
        .thumb_func
main:
        push    {r0, r1, lr}
        mov     r1, sp
        adr     r0, printf_scanf_str
        bl      scanf
        pop     {r0, r1}
        cmp     r0, #2
        bls     .Ltrue
        movs    r2, #2
.Lloop1:
        movs    r1, r0
.Ldivloop:
        subs    r1, r2
        beq     .Lfalse
        bhi     .Ldivloop
.Ldivloop_end:
        adds    r2, #1
        cmp     r2, r0
        bne     .Lloop1
.Ltrue:
        @ movs    r1, #1 @ optional, needs odd load address but will print 1 instead of a random nonzero value
.Lfalse:
        adr     r0, printf_scanf_str
        bl      printf
        pop     {pc}

printf_scanf_str:
        .asciz "%d"

Accepts a number from stdin, and prints nonzero if it is a prime, or zero if it isn't.
Walkthrough
Behold, a prime searcher that is so slow you'd swear it was Python.
It is a brute force modulo check using a subtraction loop with zero shortcuts.

Here, we use a trick with push to make space for the scanf output and save the link register.
push will subtract from sp and store the registers in ascending order in memory.
So for example, push {r0, r1, lr} will end up like this:
| sp + 0 | sp + 4 | sp + 8 |
| argc   | argv   | return |

We don't actually care about argc - we care about the space on sp. We can then just pass the stack pointer directly to scanf.
We do sorta care about argv. Not about what it points to, but that it is a valid (non-zero) pointer.
scanf("%d", &r0)
main:
        push    {r0, r1, lr}
        mov     r1, sp
        adr     r0, printf_scanf_str
        bl      scanf

Then, we can pop the result from scanf we stored into r0, and argv into r1 as a "non-zero" value.
        pop     {r0, r1}

Immediately return true for values <= 2. This is exactly why we pushed and popped r1.
        cmp     r0, #2
        bls     .Ltrue

Begin factorizing against 2.
        movs    r2, #2

Use a subtraction loop on a copy of r0 to check if r0 % r2 == 0.
Specifically, the subs will reach zero on an even multiple and set the zero flag (which corresponds to the eq condition). Otherwise, we loop until it underflows (not hi)
.Lloop1:
        movs    r1, r0
.Ldivloop:
        subs    r1, r2
        beq     .Lfalse
        bhi     .Ldivloop

Increment the number we factor against and loop if it is not equal to r0.
.Ldivloop_end:
        adds    r2, #1
        cmp     r2, r0
        bne     .Lloop1

Optionally, with the true condition, we set r1 to 1 if it is a prime.
But non-zero is "truthy" enough for us even if it is a little ugly. It will either be the last inverted modulo we tested, or the address of argv, all of which will be non-zero.
Due to how our subtraction loop works, by the time we jump to .Lfalse, r1 will already be zero.
.Ltrue:
        @ movs    r1, #1 @ optional, needs odd load address but will print 1 instead of a random nonzero value
.Lfalse:

r1 is already conveniently (and intentionally) in the right place to forward directly to printf, and all we need to do is reload the printf/scanf string to r0 (no easy way around this) and call printf.
Note that due to how pop works in Thumb, it isn't really that useful to do tail calls because we cannot pop directly into lr without a wide instruction.
printf("%d", r1)
        adr     r0, printf_scanf_str
        bl      printf

Last, pop the return address from lr we pushed earlier directly into the program counter to return from main.
        pop     {pc}

JavaScript (ES6), 42 41 bytes
!/^(.|(.+.)\2+)$/.test(Array(-~prompt()))

Based off of this regex solution. Array(+prompt()+1) creates a string of commas from the input, and it is simply passed through the (slightly edited) aforementioned solution. Array(+prompt()+1) can be replaced with 10**prompt()/9|0, but that seems to fail for numbers greater than 10.

Nice! Array(-~prompt()) is a full 3 bytes shorter than 'x'.repeat(prompt()). Did you come up with this?

Well I see it was used before.

@Deadcode I came up with it myself but I did not doubt that someone had done it before

OCaml, 50 bytes
fun n->List.(init (n-1) succ|>map((mod)n)|>mem 0);;

and it's almost idiomatic and readable.
just sad that init begins at 0 and not 1, could have saved a lot on that :(

Knight, 24 bytes
O&-=x+0P=iT?x;W%x=i+1iNi

Prints true for primes, false for composite numbers.
# print the output of the entire body
OUTPUT
  # If the number's one, then `&` returns `false`. otherwise we execute the rhs.
  &

    # `>` will coerce `i` to a number, and return `TRUE` unless `x` is one.
    >
      = x (+ 0 PROMPT) # set `x` to the input value
      = i TRUE

    # We know `x` is prime if the first `i` that `%x i` is zero for is `x`.
    ?
      x
      ;
        # evaluate the while loop then discard it.
        # note that `+ 1 i` will coerce the initial `TRUE` to a `1`.
        WHILE % x (= i + 1 i)
          NULL # ignore the body

        # the return value of `;` is `i` here. It'll be equal to `x` for primes.
        i

///, 145 bytes
/~/\/\///$/\\\\~%/+**~I/*~>**/^=$=^=$%|$+$I^^%|$%^%|$+^^%|$+^+|^^=$+^=$=^^+$*^-$**^^-$*^+$*^>~^/\~/>*~/>~>I/||/1~=\=1~/=\=|=/1~=~/*~/|~/11/1/==|=

Try it online!
Outputs 1 for composite numbers (not prime), and nothing for prime numbers. I am very happy I was able to post the first answer in my favorite language on a popular question, with a fairly good score too :)
Takes input in unary asterisks, ie. input = number of asterisks
/~/\/\///$/\\\\~%/+**~I/input here~>**/...
/~/\/\///$/\\\\~%/+**~I/*~>**/...    # 1
/~/\/\///$/\\\\~%/+**~I/**~>**/...   # 2
/~/\/\///$/\\\\~%/+*****~I/*~>**/... # 6

Ungolfed: Try it online!
Explanation:
/>**/.../ Repeats n/2 times, so we don't divide the input by itself
...+**... Starts counter at 2 so we don't divide by 1
If the input is divided evenly by any of the remaining numbers, it is not prime.
We need to "export" the current counter value to outside the loop, because there is no way to only target the counter in the current iteration, since all the iterations are copies of each other. We do this by writing it after the == at the end.
The ^ are escaped /'s in the loop, I unescaped the loop code below
/+\*/-\**/ /-\*/+\*/ Increment counter
/=\=/=\+**|\+\I/ This adds +counter|+input at the end
/+**|\+**/+**|\+ replaces +counter|+counter, which has the effect of repeatedly subtracting the counter from the input, or counter%input. Ex.
/+**|+**/+**|+/
+**|+********
gives:
+**|+********
+**|+******
+**|+****
+**|+**
+**|+

/+**|\+/+|/ deletes the +counter, just leaving +|remainder
/=\+/=\= / resets the printer, and deletes the + just leaving |remainder
After the loop, we are left with the remainders of each division, separated by | (in the ungolfed, there are also spaces).
/||/1/ 2 |'s next to each other means the remainder in between was 0
Everything else deletes garbage, or handles edge case stuff with 1 and 2.

tinylisp, 87 bytes
(load lib/math
(d f(q((n k)(i(e n k)1(i(mod n k)(f n(+ k 1))0
(d F(q((n)(f(s n(e 1 n))2

Try it online!
If anyone knows a way to use default arguments in tinylisp, I would very much appreciate it.
This answer only uses the math library and built-ins. It is shorter than the other tinylisp answer's pure version.
Explanation
Defines f, a function taking in n (main number) and k (factor). Returns 1 if k is equal to n (we have gone through all factors up to n without stopping) and otherwise, we check if n is divisible by k. If so, we return 0, otherwise, we return f called with n and k plus 1.
Then, we define the main function F which takes in only the main number, and sets k to 2.
-10 bytes thanks to @Razetime. -7 bytes thanks to @DLosc. Added some bytes to account for n = 1 case.

lib/math has a prime? function which is still a valid answer.

@Razetime yes, was already covered by another answer.

also you can remove all the end of line closing parens

@Razetime Ah, thanks for that.

Try it online!

Sadly, there are no default arguments in tinylisp (unless you use a variadic function and check the number of arguments by hand, which almost certainly costs more bytes). You may be interested in the related language Appleseed, which does support default arguments.

@DLosc Thanks. Didn't know that standard tricks such as adding/subtracting booleans worked in tinylisp too!

(load library is 1 byte shorter than lib/math

rSNBATWPL, 49 bytes
print{n=input{};(i~cond{n%i}{{i- 1}}$i*i<2)$n- 1}

Recursive solution, as a full program. As a function, it's 34:
n~(i~cond{n%i}{{i- 1}}$i*i<2)$n- 1

ARBLE, 5 bytes
prime

Try it online!
Slightly more interesting solution, 45 25 bytes
sum(range(2,n-1)|nt(n%x))

Returns falsey for primes, truthy for non-primes.
Try it online!

Shasta v0.0.8, 31 bytes
{(all(map(range2$){|a|(%$a)}))}

Explanation:
{                   ; function($):
  (all              ;   are all truthy (i.e. non-zero):
    (map            ;     map over
      (range 2 $)   ;       the range from 2 to $
      {|a| (% $ a)} ;       function(a): $ mod a
    )               ;     end map
  )                 ;   end all
}                   ; end function

No online interpreter yet, but installation instructions are at the GitHub link and I've run it against several test cases on my machine.

TypeScript's Type System, 111 bytes
type P<N,B extends 1[]=[1,1],A=N>=N extends B?1:A extends[...B,...infer I]?P<N,B,I>:A extends[]?0:P<N,[...B,1]>

Try it at the TypeScript Playground!
This is a recursive generic type P taking unary number N as a list of 1s. Outputs 1 if the input is prime, and 0 otherwise. Exception-throws a recursion error for input 1, indicating falsey.
I thought primality test would be a lot longer than it ended up being so I'm pretty pleased.
type P<                    // recursive type P
  N,                       // takes unary number N
  B extends 1[]=[1,1],     // and unary number B which defaults to 2
  A=N                      // A is used to determine divisibility
>=
  N extends B?1            // if B == N, N is prime; return 1
  :A extends[...B,         // else if B fits in A
    ...infer I             //   let I be the difference
  ]?P<N,B,I>               //   recurse with A = I
  :A extends[]?0           // else if A == 0, N isn't prime; return 0
  :P<N,[...B,1]>           // else recurse with B + 1

Uiua, 19 bytes
?¬(¬∊0◿↘2⇡.)=1.⧻&sc

Explanation:
?¬(¬∊0◿↘2⇡.)=1.⧻&sc
               ⧻&sc  # pushes n to the stack (read from STDIN in unary)
            =1.      # pushes 1 if n=1, otherwise 0
?¬(        )         # if ^^ = 1, invert the remaining 1 and finish, otherwise run the function in parentheses
      ◿↘2⇡.          # replace n with an array of all n mod k for 1 < k < n
   ¬∊0               # 1 if there is no 0 in that array

Welcome to CG&CC, and great first answer! You can cheat the input format a bit by taking unary input to golf parse to ⧻ for -2 bytes.

"if there are any 0s in a list" can be done in two bytes: 0∊. Btw, this code incorrectly classifies 1 as a prime.

JavaScript, 50 47 bytes
n=+prompt();for(i=2;n%i&&i*i<n;i++);n<3?n-1:n%i

This is a basic translation of @steveverrill's C answer :)

"Write a full program that..."

It is now a full program, and I have attributed you at the bottom of my answer :)

I believe you need an alert or something to output from a full program in JS?

@FryAmTheEggman I'd say that a web browser's console counts as a standard JS interpreter, and pretty much all consoles output the result. This outputs 0 (which is falsy) if the number is not prime.

You could save three bytes by getting rid of the 'n' in prompt('n'). I believe moving the i++ into the condition, like so: for(i=2;n%i&&i*i++<n;); would also save a byte.

@Sam Per this: http://meta.codegolf.stackexchange.com/questions/803/javascript-standards-for-io
We should be using alert or some other method to output with JavaScript. I've been hit with it before too.

@ETHproductions & is binary AND. i*i<n gives true or false (converted to binary 1 or 0). n%i can give an even number like 4. 4 && true is true, but 4 & 1 is 0

@Sam Drop the + from before prompt(). It saves one byte. Also, you can write the first bit like this, saving another byte: for(n=prompt(i=2);

GolfScript, 15 bytes
~:z,{)z\%!},,2=

This uses trial division:

stores the input in variable z
computes the remainder of dividing z by all numbers from 1 to z
expects to find a remainder of 0 exactly 2 times

Try it here.

Perl, 38 or 47 bytes
use ntheory":all";say is_prime(shift);

Prints 0 if composite, 2 if definitely prime, 1 if a probable prime.  The results for all 64-bit inputs are deterministic.  With 0.53+ this extends to 82-bit inputs.  It's also sometimes done for up to 200-bit inputs (special form or very easy proof).  The probable prime test is an extra-strong BPSW test followed by 1-5 random-base Miller-Rabin tests.
use ntheory":all";say is_provable_prime(shift);

Uses BLS75-T5 or ECPP to prove the result.  Deterministic for all inputs.  Very fast to ~500 digits, works pretty well to 1000 or so digits.
This is included in Strawberry Perl for Windows.  Certainly using a module is iffy under the golfing loopholes, but this is a normal module and Perl is all about CPAN.  It's also ridiculously faster and more useful than the clever but stupid regex.

What does "probably prime" mean?

It means it passed some probabilistic prime test that, very rarely, might give a false positive, and you may optionally want to run a more thorough test.

For ntheory, it means it passed an ES BPSW test (that has no counterexamples found in the 35 years since it was introduced) plus one or more extra random-base Miller-Rabin tests.  I just added the new result for deterministic M-R testing out to ~82 bits.  A bit stronger than Mathematica's PrimeQ function.
Primality proofs can be done, but very few people care vs. good probable prime tests.  Arguably the chance of failure is smaller than a software or hardware error in the proof code.  Not to mention most people want the result for a 2000 digit number in 0.1 seconds instead of 1,5 hours.

The challenge explicitly asks for non-probabilistic solutions.

@MartinBüttner Adjusted text and also asked the challenge to be more specific about what "deterministic" means.  Thanks.

K, 25 bytes
`0:$~x!1+*/1+!(x:. 0:`)-1

How should this be run? I tried kona/k program <<< input, but that doesn't seem to work.

Lua, 71 67 bytes
n=io.read"*n"for i=2,n-1 do if n%i==0 then r=1 end end print(not r)

Ungolfed:
n=io.read"*n"
for i=2,n-1 do
    if n%i==0 then
        r=1
    end
end
print(not r)

This program just uses trial division to find if a number is prime or not.
3 bytes saved thanks to @Ruth Franklin

You can save a couple of bytes by using r=1 instead of r=true (as not 1 is false anyway)

Ah okay, thanks for the tip :)

Inputs less than 2 (1, 0, and negative numbers) all return true.

Fortran 90, 208 bytes
program a
integer::n,i
logical::p
read(*,*)n
if(n==2) then
p=.true.
else if(n<2 .or. mod(n,2)<1) then
p=.false.
else
p=.true.
do i=3,n-1,2
if(mod(n,i)<1) then
p=.false.
exit
endif
enddo
endif
write(*,*)p
end

This uses trial division. Not a whole lot has been golfed here beyond removing spaces. Here it is with spaces for readability:
program primes
    integer :: n, i
    logical :: p

    ! Read n from STDIN
    read (*,*) n

    if (n == 2) then
        p = .true.
    else if (n < 2 .or. mod(n, 2) == 0) then
        p = .false.
    else
        p = .true.
        do i = 3, n-1, 2
            if (mod(n, i) == 0) then
                p = .false.
                exit
            endif
        enddo
    endif

    ! Write a logical to STDOUT
    write (*,*) p
end program

Surely need a space before then?

@EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Unfortunately yes.

APL, 13 bytes
2=0+.=X|⍨⍳X←⎕

Inefficient, but it works. A number is a prime if it is only evenly divisible by 1 and itself, so it just tests all of these. Output is 0 or 1.
Explanation:
          X←⎕  ⍝ read a number, store it in X
      X|⍨⍳      ⍝ X mod [1..X]
  0+.=          ⍝ count the 0s
2=              ⍝ are there 2?

Pharo, 7 bytes
isPrime

Pharo is an open source flavour of Smalltalk, a fork of Squeak. All integer instances understand the message isPrime and will respond with a boolean value. To quickly test this, simply select the text containing the number and the message (e.g. 1 isPrime) and "print-it" (or "inspect-it") from the context menu or via keyboard shortcut.

For anyone interested, here's the implementation of that method on the class Integer:
isPrime
    "Answer true if the receiver is a prime number. See isProbablyPrime for a probabilistic
    implementation that is much faster for large integers, and that is correct to an extremely
    high statistical level of confidence (effectively deterministic)."

    self <= 1 ifTrue: [ ^false ].
    self even ifTrue: [ ^self = 2].
    3 to: self sqrtFloor by: 2 do: [ :each |
        self \\ each = 0 ifTrue: [ ^false ] ].
    ^true

So the receiver of this message first covers the base cases (numbers <= 1 aren't prime, even numbers are only prime if they're 2), then checks each odd number from 3 to the floor of its squareroot to see whether dividing itself by each of those numbers results in a zero remainder. If such a divisor is found, false is returned, otherwise true. As the method comment states, there is also a faster (but probabilistic) implementation.
And just for fun, because Smalltalk is so simple with collections, here's how to get a collection of prime numbers up to 100:
(1 to: 100) select: [:each | each isPrime]

The output would be:
#(2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97)

I'm pretty sure (but unable to confirm) that the same method exists in Squeak, and probably several other flavours of Smalltalk. If so, please feel free to update this answer.

Clojure, 124
Full program, reading standard input and writing to standard output as required by the terms.
(let[n(read-string(first *command-line-args*))](print(and(> n 1)(=(reduce #(* %1(if(=(mod n %2)0)0 1))1(range 2 n))1))))

Obviously inefficient to test all the way up to n but trying to be clever with (range 2 (inc (int (Math/sqrt n)))) adds length.
Ungolfed version:
(let
    [n (read-string (first *command-line-args*))]
  (print
   (and
    (> n 1)
    (=
     (reduce #(* %1
                 (if (= (mod n %2) 0)
                   0
                   1)
                 )
             1
             (range 2 n)
             )
     1
     )
    )
   )
  )

Put in file prime.clj, execute as:
java -cp location-of-clojure.jar-in-your-system clojure.main prime.clj 1

E.g. in my system I get:
$ java -cp ../../repo-wide-libs/clojure.jar clojure.main prime.clj  1
false
$ java -cp ../../repo-wide-libs/clojure.jar clojure.main prime.clj  7
true
$ java -cp ../../repo-wide-libs/clojure.jar clojure.main prime.clj  8
false

Is there a way to remove any of those spaces? Since this is Lisp-like, you could probably take out the ones before parentheses.

yeah so this overflows easily, just uploaded version that doesn't overflow (3 chars longer)

jq, 38 bytes
. as$n|[range(2;.)]|all($n%.>0)and$n>1

Sample run:
bash-4.3$ jq '. as$n|[range(2;.)]|all($n%.>0)and$n>1' <<< 2015
false

On-line test:

2015
251

[.>1,.%range(2;.)>0]|all works for 24: https://tio.run/##yyr8/z9az85QR0@1KDEvPVXDyFpP084gtiYxJ@f/fyMuYy5DQy5DYy5zYy4uAy5DLhMuI1MDLmNLAA

Wow! That's great @ovs. Sure you not want to post it as standalone solution? It's far better than mine to be mentioned in the same answer.

Perl 6, 16 bytes
Using built-ins is allowed (even if makes for a boring answer), and this is about shortest solutions, so...
say is-prime get

get obtains a line from STDIN, is-prime when used on string converts input to integer, say outputs the boolean.

Common Lisp, 111 88 bytes
(defun p(n c)(cond((= n 1)0)((= n c)1)((eq(rem n c)0)0)(t(p n(1+ c)))))(print(p(read)2))

Try it online!
I'm kinda new to Lisp, so this could probably be improved. It's a very straightforward algorithm.
Ungolfed and commented:
(defun primep (n c)                ; define a function p with args n and c
    (cond                          ; conditional statement similar to switch-case
        ((= 1 n) 0)                ; if n is 1, return 0. Difficult to handle this.
        ((= n c) 1)                ; if c = n, then we have gotten all the way through
                                   ; without finding a single divisor. It's prime; return 1.
        ((eq (rem n c) 0) 0)       ; if n is evenly divisible by c, return 0
        (t (primep n (1+ c)))      ; if all else fails, increment c and recurse
    )
)
(print (primep (read) 2))          ; eval one line from stdin, call primep with an initial
                                   ; count of 2, and print the result

C,59 bytes
main(i,j){scanf("%d",&i);for(j=2;i%j++;);printf("%d",j>i);}

It outputs 1 if the input is a prime and 0 otherwise.

+1 This very nearly fails for an input of 1, where the for() loop will repeat almost forever. But eventually j will overflow and become negative, and then count back up again towards zero. When j==-1, i%j==0, so the loop exits and the program outputs 0 because 1>-1. This is fortunate because the next iteration would raise a divide-by-zero error.

Minkolang, 29 5 bytes
I have since added a built-in for primality testing (it uses a parallelized version of the Sieve of Sundaram).
n2MN.

Explanation
n     Take integer from input
2M    Push 1 if prime, 0 otherwise
N.    Output as integer and stop.

Old version (does not use a built-in):
This was surprisingly long. I'll probably implement a built-in for this (since primality checking will probably be useful elsewhere).
nd2`4&1-N.d2-[0ci2+%3&0N.]1N.

Explanation
n                                Take integer as input.
 d2`4&1-N.                       Output 0 if 1, 1 if 2.
          d2-[           ]       Trial division loop.
              0ci2+%             Check to see if it's divisible by <loop counter>.
                    3&0N.        If so, output 0 and stop.
                          1N.    It's prime! Output 1 and stop.

TeaScript, 5 bytes
$P(x)

Returns true if input is a prime and false of it is a composite number.
Try it online here Does NOT work in Chrome. Input is given in the first field.

Carrot (version ^3), 3 bytes
#^P

Basically takes the input (#) and checks if it is a prime number (P) or not.
Note that this program takes the input as a string and,without converting it into a integer, it checks if the number is a prime or not.
Try it online here.
Although my programming language has been created after the challenge, it was not created to "abuse" this challenge.

This is scary good. +1

Stack, 132 bytes:
'' '' input num `n set 2 `i set { n i % 0 = n 1 = or { 0 print } { i n 2 - gt { 1 print } { i 1 + `i set p } ifelse } ifelse } `p def p

Your basic test every number from 2 to n primality test.

Unnecessary whitespace is unnecessary? '' input num `n set 2 `i set { n i % 0 = n 1 = or { 0 print } { i n 2 - gt { 1 print } { i 1 + `i set p } ifelse } ifelse } `p def p saves 10 bytes

@towerofnix thanks

pl, 1 byte
≡

Try it online.
At the moment, pl uses a lazy trial division builtin. I'll replace it with something that doesn't suck later.

Is that really one byte? I count three but I'm not sure what the rules are.

pl uses CP437 as its encoding. This char is one byte (0xF0) in it.

And now I know a thing. Thank you!

ROOP, 17 bytes
I
w#H

 P
  w
  O

The w operator reads a number from the keyboard because it has an input object above (I). The input object moves to the right and the number created falls down. The P operator checks whether the number is prime and places a 1 or a 0 on the right (eliminating the number). Then the input object is moved to the right, the number created can not move anywhere. The operator H is activated because it has a object above and terminates the program at the end of all operators. The operator w, puts the number 1 or 0 in the display.

F#, 99 88 bytes
[<EntryPoint>]
let f a=
 let i=int a.[0]
 Seq.forall((%)i>>(<)0)[2..i-1]|>printfn"%b";0

Explanation of the interesting part:
                      [2..i-1]              // Generate a list of possible divisors (from 2 to i-1) - for 2, this is an empty list.
Seq.forall(          )                      // Check if none of them are actual divisors, that is
           (%)i>>(<)0                           // That i % it is greater than 0. This is equivalent to (fun d -> i % d > 0)
                              |>printfn"%b" // And print the answer as a boolean

Update: Turns out, the entry point doesn't have to be called "main", and the argument array doesn't have to be called "argv"! =)

Oracle SQL 11.2, 73 bytes
SELECT SUM(DECODE(MOD(:1,LEVEL),0,1,0))-2 FROM DUAL CONNECT BY LEVEL<=:1;

Return 0 if prime, any other value is false

A slightly smaller version SELECT MIN(MOD(:1,LEVEL+1))FROM DUAL CONNECT BY LEVEL<:1-1; that will return 0 or 1

Jolf, 2 bytes
Try it here!
m{

Simple. m{ is the isPrime function of the math module, and j is the (implicit) user input as a number.

VHDL, 236 bytes
entity e is
port(n:natural;b:out bit);end;architecture a of e is
function p(n:natural)return bit is
begin
if n=1 then
return'0';end if;for i in 2 to n-1 loop
if n mod i=0 then
return'0';end if;end loop;return'1';end;begin
b<=p(n);end a;

The input n is an input port of the entity e; a natural number (starts at 0 for VHDL). b is an output port of entity e; a bit (meaning '1' or '0'). This works by the ever-famous method of trial division, with a special case for 1. This is what it looks like formatted nicely:
entity e is
    port(   n : in natural;
            b : out bit);
end;

architecture a of e is
    function p(n:natural) return bit is
    begin
      if n=1 then
          return '0';
      end if;
      for i in 2 to n-1 loop
          if n mod i=0 then
              return '0';
          end if;
      end loop;
      return'1';
    end;
begin
    b<=p(n);
end a;

Here's the testbench I used for verification:
entity m is
end;

architecture a of m is
    signal i_n : natural := 2;
    signal i_b : bit;

    type int_vector is array(natural range<>) of natural;

    constant primes : int_vector := (2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97);

    function is_prime(n : natural) return boolean is
    begin
        for i in primes'range loop
            if n=primes(i) then
                return true;
            end if;
        end loop;
        return false;
    end;
begin
    x:entity work.e port map(n=>i_n, b=>i_b);
    process
    begin
        for i in 1 to primes'right loop
            i_n <= i;
            wait for 10 ns;
            if is_prime(i) then
                assert i_b='1';
            else
                assert i_b='0';
            end if;
        end loop;
        report "finished" severity error; -- error to stop simulation
    end process;
end a;

This is the result.

@ais523 except the question specifies that it must be a full program

Reng v.1, 36 39 bytes
This tests if the input is a prime. (+3 bytes because I forgot to check if input = 1)
i:11#x   eqv0n~
x1+#x:x,?v$\
    ~nex$/

All because I forgot to implement member switching. I am rather proud of this, however, because it uses an interesting feature of Reng: you can redefine any character's meaning. In this case, we see constant redefinition.
i takes input, and 1 pushes 1. We also define x as 1 (1#x) and print zero and terminate if the input is 1 (eqv0n~). Then, the pointer is directed to the next line, x1+#x:x,?v$\. (The last character is a NOP for this instance.)
For the first iteration, 1+ increments x, yielding 2. This is where our trial division starts. #x defines x to be the top element of the stack, in this case, 2. : duplicates the TOS, the input element, and x puts down its value, 2 in this case. , is the modulus operator, and yields i % x. If this is zero, we are directed downwards by v. Otherwise, we drop the modulus and redo the line again.
When we are directed downward by v, we meet / which executes the line ~nex$, equivalent in a left-to-right form to $xen~. $ drops a value, x lays down x, and e checks for equality. If they are equal (in the case that x is the input), this is 1. Otherwise, this is 0.
Test cases
The programs pictured are still valid, but fail to handle 1 correctly, unlike the program above.
Is 5 a prime?
Yes!

Is 169 a prime?
No!

Fuzzy Octo Guacamole, 21 bytes
^-!.1C[d2ss.p*.+]s.Zm

Outputs 0 for false, 1 for true.  Thanks to @xnor for the algorithm.
Explanation:
^-!.1C[d2ss.p*.+]s.Zm
^                      # Get Input
 -                     # Decrement
  !                    # Set for-loop counter
   .                   # Swap stacks
    1C                 # Set both stacks to [1].  (push 1 and copy to other stack)
      [         ]      # For loop for duration of input - 1
       d2              # Duplicate the top of stack and push 2 after
         ss            # Put them on the other stack, in reverse order.
           .           # Switches stacks
            p          # Power function. x^y (ToS^2)
             *         # Multiply
              .+       # Move back to the other stack and increment
                ]      # (repeat)
                 s.    # Move the ToS over and go with it
                   Z   # Reverse the stack.
                    m  # Modulus, x%y.
                       # (implicit output)

We start with each stack having 1.  Let the bottom of one stack be n, the other bottom be P.  We multiply P by n^2, and then increment n. Do this n-1 times.  Then take P%n.

Labyrinth, 21 bytes
?
:
}()"{
{: *}{:*{%!

Terminates with an error, with the error message going to STDERR.
Try it online!
Explanation
This uses the same approach based on Wilson's theorem as Sp3000's answer, but I managed to decompose his 3x3 loop into two 2x2 loops which is generally better for golfing Labyrinth.
Labyrinth primer:

Labyrinth has two stacks of arbitrary-precision integers, main and aux(iliary), which are initially filled with an (implicit) infinite amount of zeros.
The source code resembles a maze, where the instruction pointer (IP) follows corridors when it can (even around corners). The code starts at the first valid character in reading order, i.e. in the top left corner in this case. When the IP comes to any form of junction (i.e. several adjacent cells in addition to the one it came from), it will pick a direction based on the top of the main stack. The basic rules are: turn left when negative, keep going ahead when zero, turn right when positive. And when one of these is not possible because there's a wall, then the IP will take the opposite direction. The IP also turns around when hitting dead ends.

Now we can look at the code. The program starts with a short linear (vertical) bit:
?   Read input N as an integer and push onto main.
:   Duplicate N.
}   Move one copy over to aux.

The IP is now at a junction, and in fact the small 2x2 block acts as a loop which is traversed in clockwise order:
(   Decrement N. If it hits zero, we exit the loop.
:   Duplicate N.
{}  Move a value over from aux and push it back. Together this does nothing.

So this loop leaves all the numbers from N-1 down to 0 on the main stack. Now there's the single ), which increments that 0 back up to 1, such that all the non-zero numbers on top of the stack will multiply together to (N-1)! (including the special case of 0! == 1).
The next 2x2 block is a loop which performs this multiplication and its traversed in counter-clockwise order. The tricky part is that we need to check the value below the product to see if we're done, otherwise we'd end up losing the product by multiplying it with an implicit 0 below.
"   No-op, does nothing.
*   Multiply the top two values on main.
}   Move the product over to aux, exposing the value below. If that's zero,
    we exit the loop.
{   Pull the product back onto main for the next iteration.

Now the main stack is empty and the aux stack contains (N-1)! on top of N. Time to wrap things up:
{   Pull (N-1)! over from aux.
:*  Duplicate and multiply, squaring the factorial.
{   Pull N over from aux.
%   Take modulo, computing (N-1)!^2 % N.
!   Output the result.

Now the IP hits a dead end and has to turn around. The next thing it tries to execute is % but that would now attempt to compute 0 % 0 which terminates with a division-by-zero error.

WistfulC, 381 bytes
if only int n were 0...
wish for "%d", &n upon a star
if n < 2 were true...
    wish "not prime" upon a star
    if wishes were horses...
*sigh*
if only int i were 2...
someday i will be n...
    if n % i were 0...
        wish "not prime" upon a star
        if wishes were horses...
    *sigh*
    if only i were i + 1...
*sigh*
wish "prime" upon a star
if wishes were horses...

Outputs prime if prime, not prime if not prime.
I went for entertainment value more than small size. Here's a golfed, (arguably) less funny version (286 bytes):
if only int n were 0...wish for "%d",&n upon a star
if n<2...wish "0" upon a star
if wishes were horses...*sigh*if only int i were 2...someday i==n...if !(n%i)...wish "0" upon a star
if wishes were horses...*sigh*if only i were i+1...*sigh*wish "1" upon a star
if wishes were horses...

You can save some bytes by return truthy/falsy values?

APL (NARS2000), 6 bytes
Function: 0∘π
Program: 0π⎕

Sesos, 40 39 bytes
0000000: 16f0be afcf9c 37fcfe 8c19d7 c671d7 668ee3 f57b33  ......7......q.f...{3
0000015: 877bc6 662edb b961ba 8763bc 666e3c 66ec01         .{.f...a..c.fn<f..

Try it online! Check Debug to see the generated binary code.
Background
To identify primes, we use a corollary of Wilson's theorem:

How it works (WIP)
The binary file above has been generated by assembling the following SASM code.
set numin
set numout

get
jmp
    jmp, fwd 1, add 1, fwd 1, add 1, fwd 1, add 1, rwd 3, sub 1, jnz
    fwd 1, sub 1, fwd 2
    jmp, rwd 3, add 1, fwd 3, sub 1, jnz
    rwd 1, sub 1
jnz
rwd 1, add 1, rwd 2
jmp
    fwd 1
    jmp, fwd 2, add 1, rwd 2, sub 1, jnz
    fwd 1
    jmp
        fwd 1
        jmp, fwd 1, add 1, rwd 3, add 1, fwd 2, sub 1, jnz
        fwd 1
        jmp, rwd 1, add 1, fwd 1, sub 1, jnz
        rwd 2
        sub 1
    jnz
    fwd 1
    get
    rwd 4
jnz
fwd 2
jmp
    rwd 1, sub 1, rwd 1, add 1, fwd 1
    jmp, rwd 1, jnz
    rwd 1
    jmp, fwd 1, add 1, rwd 1, sub 1, jnz
    fwd 2
    jmp, fwd 1, jnz
    rwd 1, sub 1
jnz
rwd 2
put

Idris, 78 bytes
main:IO()
main=let S n=length!getLine in print$0<(pow(product[1..n])2`mod`S n)

This takes input as a unary string (it uses the string length as input).
Compile this with idris -O3 or you’ll spend forever in Nat-computey hell.

Python 3.5, 58 52 58 bytes
import math;n=int(input());print(math.factorial(n-1)**2%n)

I unassumed. Thanks Dennis.
I assumed something about the way the input would be given. Thanks daHugLenny.
   import math;lambda n:print(math.factorial(n-1)**2%n)

You can save 13 bytes by using a lambda: import math;lambda n:math.factorial(n-1)**2%n

In this particular challenge, lambdas are not allowed. The spec says Write a full program that... (CC @daHugLenny)

PHP, 51 bytes
An alternative PHP answer, but required the GMP extension to be installed:
<?=gmp_strval(gmp_nextprime($argv[1]-1))==$argv[1];

Simply subtracts 1 from the input and compares the nextprime result against the input

gmp_cmp can save 3 bytes. But unfortunately, that algorithm is only probably correct, not always. +1 anyway for showing it off. :)

Clojure, 98 bytes
(let[n(Integer/parseInt(read-line))](println(and(not= 1 n)(not(some #(=(rem n %)0)(range 2 n))))))

Uses some to check if the number has any divisors, then negates the result to indicate whether or not it's prime.
A simple function would have only been 59 bytes :(
(fn[n](and(not= 1 n)(not(some #(=(rem n %)0)(range 2 n)))))

Ungolfed:
(let [n (Integer/parseInt (read-line))]
  (println
    (and (not= 1 n) ; 1 is an unfortunate special case
         (not ; Negate to indicate primality
           (some #(= (rem n %) 0) ; Check if n has any divsors...
                 (range 2 n)))))) ; in the range of 2 to (n-1)

There's a previous Clojure answer, but this beats it by a little over 60 bytes

You can also turn Integer/parseInt to read-string to save a further 5 bytes.

1: You can replace (not= 1 n) with (> n 1) to handle the edgecase of 1. 2: You can replace (not (some ...)) with (every? ...) and change the condition around a bit. 3: You can swap the fn[n] and the shorthand around to remove a space, like so: #(and(> % 1)(every?(fn[a](>(rem % a)0))(range 2 %))). These three save 7 bytes.

@Qwerp-Derp Thanks. I'll try to remember to update my answer later today.

@Carcigenicate Here's a quick reminder. :P

@totallyhuman LOL. JULY. I clearly dropped that ball. I hate to delay this again, but I'm not quite on the mental state to deal with this right now. I think I'll set a reminder on my phone

66 for the full program: (def n(read))(pr(and(> n 1)(not(some #(=(rem n %)0)(range 2 n)))))

63 with every?: (def n(read))(pr(and(> n 1)(every? #(>(rem n %)0)(range 2 n))))

Taxi, 1519 1309 bytes
Go to Post Office:w 1 l 1 r 1 l.Pickup a passenger going to The Babelfishery.Go to The Babelfishery:s 1 l 1 r.Pickup a passenger going to Cyclone.Go to Cyclone:n 1 l 1 l 2 r.Pickup a passenger going to Cyclone.Pickup a passenger going to The Underground.Go to Zoom Zoom:n.[a]Go to Cyclone:w.Pickup a passenger going to Sunny Skies Park.Pickup a passenger going to Divide and Conquer.Go to Sunny Skies Park:n 1 r.Go to The Underground:s 1 l 1 r 2 l.Switch to plan "1" if no one is waiting.Pickup a passenger going to Cyclone.Go to Cyclone:n 3 l 2 l.Pickup a passenger going to Divide and Conquer.Pickup a passenger going to The Underground.Go to Divide and Conquer:n 2 r 2 r 1 r.Pickup a passenger going to Cyclone.Go to Cyclone:e 1 l 1 l 2 l.Pickup a passenger going to Trunkers.Pickup a passenger going to Equal's Corner.Go to Trunkers:s 1 l.Pickup a passenger going to Equal's Corner.Go to Equal's Corner:w 1 l.Switch to plan "b" if no one is waiting.Go to The Underground:n 3 r 1 r 2 l.Switch to plan "z" if no one is waiting.[1]'0' is waiting at Writer's Depot.[z]'1' is waiting at Writer's Depot.Go to Writer's Depot:n 3 l 2 l.Pickup a passenger going to Post Office.Go to Post Office:n 1 r 2 r 1 l.[b]Go to Sunny Skies Park:n.Pickup a passenger going to Cyclone.Go to Zoom Zoom:n 1 r.Switch to plan "a".

Try it online!
Un-golfed with comments:
[ Test for Primality ]
[ Inspired by: https://codegolf.stackexchange.com/q/57617 ]

[ Pickup stdin and triplicate it]
Go to Post Office: west 1st left 1st right 1st left.
Pickup a passenger going to The Babelfishery.
Go to The Babelfishery: south 1st left 1st right.
Pickup a passenger going to Cyclone.
Go to Cyclone: north 1st left 1st left 2nd right.
Pickup a passenger going to Cyclone.
Pickup a passenger going to The Underground.
Go to Zoom Zoom: north.

[a]
Go to Cyclone: west.
Pickup a passenger going to Sunny Skies Park.
Pickup a passenger going to Divide and Conquer.

[ Store a copy of the original stdin ]
Go to Sunny Skies Park: north 1st right.

[ Iterate down to the next lowest number ]
[ If the input is 1, the switch will immediately output '0' ]
Go to The Underground: south 1st left 1st right 2nd left.
Switch to plan "1" if no one is waiting.
Pickup a passenger going to Cyclone.
Go to Cyclone: north 3rd left 2nd left.
Pickup a passenger going to Divide and Conquer.
Pickup a passenger going to The Underground.

[ Divide the original by the current iteration and check if it's an integer ]
Go to Divide and Conquer: north 2nd right 2nd right 1st right.
Pickup a passenger going to Cyclone.
Go to Cyclone: east 1st left 1st left 2nd left.
Pickup a passenger going to Trunkers.
Pickup a passenger going to Equal's Corner.
Go to Trunkers: south 1st left.
Pickup a passenger going to Equal's Corner.
Go to Equal's Corner: west 1st left.
Switch to plan "b" if no one is waiting.

[ Someone was waiting so it was an integer result ]
[ This is going to eventually happen when we divide by one ]
[ If the current iteration is 1, we want to return 1 as a truthy result ]
[ It it's anything higher than 1, we want to return 0 as a falsey result ]
Go to The Underground: north 3rd right 1st right 2nd left.
Switch to plan "z" if no one is waiting.

[1]
'0' is waiting at Writer's Depot.
[z]
'1' is waiting at Writer's Depot.
Go to Writer's Depot: north 3rd left 2nd left.
Pickup a passenger going to Post Office.
Go to Post Office: north 1st right 2nd right 1st left.
[ No need to return to taxi garage or even switch to the end of the program ]
[ It will output to stderr because it can't drive in the next direction and terminate the program ]

[b]
[ No one was waiting so it was not an integer result ]
[ Continue on to the next iteration ]
Go to Sunny Skies Park: north.
Pickup a passenger going to Cyclone.
Go to Zoom Zoom: north 1st right.
Switch to plan "a".

The only thing that felt golf-y when writing it was allowing it to error out instead of terminate properly.

Swift 4, 58 bytes
let n=Int(readLine()!)!;print((1..<n).filter{n%$0<1}==[1])

Try it online!
Saved a few bytes thanks to Dennis.

Wumpus, 13 bytes
I=&l2-&*=*r%O

Try it online!
Explanation
Uses Wilson's theorem in the form (n-1)!2 ≡ isprime(n) (mod n) (where isprime gives 0 or 1, respectively).
The implementation doesn't really work the way it's supposed to for n = 1, but the result still ends up being 0.
I=  Read n and duplicate it.
&l  Push the stack depth n times. Since there's another copy of n on the stack to
    begin with, this pushes 1, 2, ..., n-1, n.
2-  Subtract 2 from n.
&*  Multiply the top two numbers that many times. This essentially folds
    multiplication over the range [1,n-1], which computes (n-1)!. At
    the end of this, the stack will be [n, (n-1)!]. However, in the case
    of n = 1, we only ever pushed one element for the range, so there's
    nothing left to form the factorial and the stack contains only one
    copy of 1.
=*  Square the (n-1)!.
r   Reverse the stack. This is normally just used to swap n and (n-1)!²,
    but we're using stack reversal instead of swap (~), so that the stack
    remains unchanged for n = 1.
%   Modulo. For n = 1, this computes 0 % 1 = 0 (because there's an implicit
    zero underneath the 1 on the stack). For all other n, this computes
    (n-1)!² % n, i.e. the result of the primality test.
O   Output the result as a decimal integer.

The IP then bounces off the end of the program and starts moving left again. % tries another modulo, but there's only implicit zeros on the stack, so the program ends due to the attempted division by zero.

COBOL (GNU), 305 bytes ( +5 for compiler flags)
ID DIVISION.PROGRAM-ID.A.DATA DIVISION.WORKING-STORAGE SECTION. 1 I PIC 9(9). 1 V PIC 9(9). 1 R PIC 9(9). 1 Q PIC 9(9). 1 P PIC 9 VALUE 1.PROCEDURE DIVISION.ACCEPT V PERFORM VARYING I FROM 2 BY 1 UNTIL I=V DIVIDE I INTO V GIVING Q REMAINDER R IF R=0 THEN MOVE 0 TO P END-IF END-PERFORM DISPLAY P STOP RUN.

Compile with -free flag. (This allows ignoring formatting.)
Try it online!
Ungolfed version:
IDENTIFICATION DIVISION.    *> Required in every program header.
PROGRAM-ID. A.

DATA DIVISION.
WORKING-STORAGE SECTION.
    01 I PIC 9(9).          *> Loop index
    01 V PIC 9(9).          *> Value to test
    01 R PIC 9(9).          *> Remainder
    01 Q PIC 9(9).          *> Quotient
    01 P PIC 9 VALUE 1.     *> Is prime?

PROCEDURE DIVISION.
    ACCEPT V                                    *> Get value from input
    PERFORM VARYING I FROM 2 BY 1 UNTIL I>V/2   *> for (i = 2; i <= v/2; i++)
        DIVIDE I INTO V GIVING Q REMAINDER R    *>     Q = V/I; R = remainder(V/I)
        IF R=0 THEN MOVE 0 TO P END-IF          *>     If remainder is zero, not prime
    END-PERFORM
    DISPLAY P               *> Output result (1 or 0)
    STOP RUN.

Stax, 2 bytes
|p

Run and debug online!
Added for completeness. An internal.

tinylisp, 23 bytes
There's a library function.
(load library
(prime? 1

(Since tinylisp is incapable of taking user input, "For scoring purposes, submit the program that corresponds to the input 1.")
Try it online!

Here's a 112-byte solution using only the base language, no library functions:
(d D(q((F A N)(i(l A N)(D F(a F A)N)(e N A
(d _(q((F N)(i(D F 0 N)(e F N)(_(a 1 F)N
((q((N)(i(e N 1)0(_ 2 N))))1

The first line defines a function D that takes a factor F, an accumulator A (initially 0), and a number N; it returns 1 if N is divisible by F, 0 otherwise.
The second line defines a function _ that takes a minimum factor F and a number N; it returns 1 if N is coprime to all numbers from F to N-1, 0 otherwise.
The third line constructs an anonymous function that takes a number N; it returns 0 if N is 1, and otherwise calls _ with number N and minimum factor 2. As above, the scored code calls the anonymous function with an argument of 1.

Zephyr, 88 bytes
input n as Integer
set f to 0
for i from 1to n
if(n mod i)=0
inc f
end if
next
print f=2

Try it online!
Uses the "n must have exactly two perfect divisors in the inclusive range [1, n]" approach. Run a for loop over that range, count the numbers i for which n mod i is zero, and output at the end whether the count equals 2.

Julia 0.6, 44 bytes
n=parse(Int,ARGS[]);show(sum(n%(1:n).<1)==2)

Try it online!
Since the existing answers are invalid for the challenge and/or outdated by newer Julia versions, I'm adding a Julia answer that works in Julia 0.6.
For Julia 0.7 (and to avoid deprecation warnings in 0.6), this needs just one more byte (% becomes .%):
45 bytes
n=parse(Int,ARGS[]);show(sum(n.%(1:n).<1)==2)

Try it online!

Perl 6, 20 bytes
say get~~$_%%one ^$_

Try it online!
There's also the built-in is-prime, but I thought it would be more interesting to do it without it. Surprisingly, this is only 4 bytes longer.
Explanation:
    get                # Get a line of input
       ~~              # Smartmatch it by setting $_ to input
         $_%%          # Is input divisible by
             one       # Only one of
                 ^$_   # The range 0 to input-1?
say                    # And print

Note that this works because n%%0 is boolified to False.

05AB1E, 3 bytes
fнQ

find all factors and see if last one equals input.
Try it online!

Built-ins are allowed, so just p is enough.

Gol><>, 4 bytes
ISPh

Thanks to ASCII-only for letting me now I didn't need 2 bytes, since it was redundant.
Try it online!

The ?1 is needed??????

@ASCII-only Thank you for pointing that out, I didn't even think of that. Fixing it now!

At least in this particular implementation of Gol><>, P is implemented by the is_probably_prime function. Unfortunately, this challenge requires a deterministic primality test.

@Dennis The is_probably_prime function is a wrapper for the sympy isprime function, which is deterministic up to $2^{64}$. If the sympy library is not available, then it does a non-deterministic check.

dc, 17 22 bytes
?d*5+v[dz%rdz<M*]dsMxp

Try it online!
I've been on a bit of a dc kick lately and although there's already a dc solution here, this is 10 5 bytes shorter. It follows the I/O request of the original question, which does add two bytes for the explicit input and output (rather than the usual rules these days that allow implicit stack I/O), but okay.
This outputs zero for composite numbers and non-zero for primes.
How it works: this program builds a stack consisting of the modulo of the input with the current stack size (so the stack looks like, from bottom to top, i%2, i%3, i%4, ...), then when it decides it's gone far enough (stack size = input) it multiplies the stack as it unwinds the recursion.

This fails for 1 and 2.

Oof, you're right. Not sure how I missed that. It took me five bytes to fix (by precomposing with d*5+v, i.e., x -> int(sqrt(x^2+5)), i.e., 1->2, 2->3, n->n for n>2)

K (oK), 14 19 bytes
Solution:
2=+/d=_d:x%!x:. 0:`

Try it online!
Example:
root@c957fa0dccbd:/ok# echo 1 | node repl.js examples/prime.k
0
root@c957fa0dccbd:/ok# echo 2 | node repl.js examples/prime.k
1
root@c957fa0dccbd:/ok# echo 5 | node repl.js examples/prime.k
1
root@c957fa0dccbd:/ok# echo 97 | node repl.js examples/prime.k
1

Explanation:
Calculate number of factors for input, if equal to 2, then it's prime.
2=+/d=_d:x%!x:. 0:` / the solution
                0:` / read from stdin
              .     / value (ie convert "123" > 123)
            x:      / store input as x
           !        / range 0..x
         x%         / x divided by ...
       d:           / store as d
      _             / floor
    d=              / d equal to ...
  +/                / sum
2=                  / 2 equals?

Rust (full program), 124 bytes
fn main(){let s=&mut"".into();std::io::stdin().read_line(s);let n=s.parse().unwrap();print!("{}",n>1&&(2..n).all(|x|n%x>0))}

Try it online!
How complicated it has to be to read an integer from stdin...

using args is shorter 105 bytes

DIVCON, 8 bytes
Prequisities: Enter 1 into the INPUT_MAX prompt.
i*[;-=o]

Explanation
"Partition" by * here means solving x * y = a - a is the original accumulator value. x and y needs to be as close as possible. In addition, the following equality must be satisfied: x>=y
         Description     | Example(0) | Example(1)
         ----------------+------------+-----------
i        Take an input   |  12        | 13
 *       Partition by *  | 4, 3       | 13, 1
         ----------------+------------+-----------
  [      Left branch     |   4        | 13
         Do nothing      | *discarded*| *discarded*
         ----------------+------------+------------
   ;     Right branch    | 3          | 1
    -    x - 1           | 2          | 0
     =   x == 0?         | 0          | 1
      o  Print this value| OUT: 0     | OUT: 1
         ----------------+------------+------------
       ] End both branches

Actually, there is another implicit reverse computation. But, since INPUT_MAX is 1, the extra prompting from i is disabled.

MAWP, 48 46 54 bytes
@1A<:.>{1A<1:.>2M}!1A[/!!\!/P\!/WA<:.>{%}\2A?0{1M}]1:.

-2 bytes from Dion's suggestion.
+8 bytes after fixing the problem with 1 as input.
Prints 1 for prime and 0 for non-prime. Can probably be golfed by a few more bytes, since it checks for 2 at the beginning first.
Try it!

Should work as expected now.

Looks good now. Can you explain how it works?

checks for 1 first, then 2, then moves on with a loop till it finds any divisor.

Rockstar, 119 117 107 bytes
Outputs -0.5 for primes and 0 for composites.
listen to N
let D be N
let P be N-1
while P and D-2
let D be-1
let M be N/D
turn M up
let P be N/D-M

say P

Try it here (Code will need to be pasted in)
listen to N         :Read input string into variable N
let D be N          :Initialise D as N
let P be N-1        :Initialise P as N-1, which will be 0 (falsey) if N=1
while P and D-2     :While P and D-2 are not zero
let D be-1          :  Decrement D
let M be N/D        :  Assign N/D to variable M
turn M up           :  Round M up
let P be N/D-M      :  Reassign N/D-M to P
                    :End while loop
say P               :Output P

GolfScript, 14 bytes
~.,{*.!+}*.*\%

Try it online!
This outputs this version of Wilson's theorem, used in other answers to this question:
\$(n-1)!^2 \mod{n}\$
This outputs 1 if it is a prime and 0 if it is not.
~                 # Push n
 .,               # Range from 0 to (n-1)
   {*.!+}         # Push block without executing
         *        # Fold
          .*      # Square, it could also be 2?, but for large values of n there would be an error message
            \%    # Mod n

What the block does:
    *             # Multiply
     .!           # Is it 0?
       +          # Add 1 if it was 0 and 0 if it wasn't

This uses 3 bytes to avoid the 0, there are ways of removing it from the array using 2:
~.,(;{*}*.*\%

Try it online!
The problem here is when the input is 1, in this case after removing the 0 we wouldn't have any number to multiply.

Oops sorry I made that mistake in the LaTeX

ArnoldC, 707 636 618 bytes
Saved 71 89 bytes thanks to pppery!
LISTEN TO ME VERY CAREFULLY f
I NEED YOUR CLOTHES YOUR BOOTS AND YOUR MOTORCYCLE n
HEY CHRISTMAS TREE k
YOU SET US UP 2
HEY CHRISTMAS TREE l
YOU SET US UP 1
HEY CHRISTMAS TREE p
YOU SET US UP 1
GET TO THE CHOPPER l
HERE IS MY INVITATION n
LET OFF SOME STEAM BENNET k
ENOUGH TALK
STICK AROUND l
GET TO THE CHOPPER p
HERE IS MY INVITATION n
I LET HIM GO k
LET OFF SOME STEAM BENNET 0
KNOCK KNOCK p
ENOUGH TALK
GET TO THE CHOPPER k
HERE IS MY INVITATION k
GET UP 1
ENOUGH TALK
GET TO THE CHOPPER l
HERE IS MY INVITATION n
LET OFF SOME STEAM BENNET k
KNOCK KNOCK p
ENOUGH TALK
CHILL
TALK TO THE HAND p
HASTA LA VISTA, BABY

Try it online!
Doesn't look like anyone's posted an ArnoldC answer here yet, and I thought the best way to respect the Terminator would be by writing an answer in his language.

Only 636 bytes as a function.

@pppery THANKS. ENOUGH TALK. HASTA LA VISTA, BABY.

Can be further reduced to 618 bytes by using the nonstandard output technique of a function outputting to STDOUT, which is allowed since functions may output via the same methods as full programs

@pppery Thanks again, I never thought anyone could golf in ArnoldC!

CSASM v2.1.2.2, 207 235 bytes
Prints a 1 (truthy) if the input is a prime integer, 0 (falsy) otherwise.
Truthy values in CSASM are non-zero numbers, non-\0 chars and non-null strings/arrays/objects.
Falsy values in CSASM are zero, the \0 character or null strings/arrays/objects.
func main:
in ""
conv i32
pop $a
push $a
push 2
comp.gte
push $f.o
brtrue a
br b
.lbl a
push 2
dup
pop $1
push $a
sub
brfalse d
.lbl c
clf.o
push $a
push $1
rem
brfalse b
inc $1
push $1
push $a
comp.lt
push $f.o
brtrue c
.lbl d
push 1
print
ret
.lbl b
push 0
print
ret
end

Commented and ungolfed:
func main:
    ; Get the input, convert it to an integer and store it in the accumulator
    in ""
    conv i32
    pop $a

    ; if $a < 2, then $a is not prime
    push $a
    push 2
    comp.gte
    push $f.o
    brtrue initLoop
    br notPrime

    .lbl initLoop
    ; Initialize the loop counter and check if $a == 2
    ; If $a is 2, return truthy early
    push 2
    dup
    pop $1
    push $a
    sub
    brfalse prime

    .lbl loop
        ; Clear the comparison flag
        clf.o

        ; If $a % $1 == 0, then $a is not prime
        push $a
        push $1
        rem
        brfalse notPrime

        ; Loop until $1 >= $a
        inc $1
        push $1
        push $a
        comp.lt
        push $f.o
        brtrue loop

    .lbl prime
    ; $a is prime
    push 1
    print
    ret

    .lbl notPrime
    ; $a is not prime
    push 0
    print
    ret
end

Arduino, 146 143 bytes
#define S Serial
int p=0,d=1;void setup(){S.begin(300);}void loop(){while(S.available())p=p*256+S.read();if(p&&!(p%++d%p)){S.print(p==d);p=0;}}

Based on the current top answer for C++. I'm not convinced my adaptation is optimal.
Reading in a number from the Serial input is actually pretty annoying in Arduino. Serial.available() gives the number of unread bytes, but unfortunately it caps out at 64, which is too small for me to use unary for this challenge. Instead, I opted to interpret the input as a byte array.
Bitshift is lower precedence than addition, and (p<<8) is longer than p*256 (note the parentheses needed).
In this case, a while loop is actually shorter than a for loop, by 1 character.
Explanation:
#define S Serial /* This macro is worth it in the end, but not by much */

int p = 0, // the case p = 0 is also taken to mean not to even attempt this anyways
    d = 1;

void setup() {
  S.begin(300); // standard is 9600 but 300 is shorter
}

void loop() {
  while (S.available()) // truthy while there are unread bytes
    p = p * 256 + S.read();

  if (p && !(p % ++d % p)) { // second condition from the C++ answer
    S.print(p == d); // method from the C++ answer
    p = 0; // reset this to stop trying
  }
}

I suppose this technically comes with the caveat that no byte of the number can be 0 (so 256 wouldn't work; it's 0x0100), as the serial port takes in null-terminated strings. That said, it's only two more characters to make a version that accepts numbers written in decimal -- just replace p*256+S.read() with p*10+S.read()-48.
Original:
int p=0,d=1;void setup(){Serial.begin(300);}void loop(){while(Serial.available())p=p*256+S.read();if(p&&!(p%++d%p)){Serial.print(p==d);p=0;}}

K (ngn/k), 18 bytes
1=+/1>(!x)!'x:.1:0

Try it online!

WTFstack, 13 bytes
1g{?(!)?/x<{;

WTFstack is my new programming language in which mathematical operations work on the entire stack at once.
Returns a stack of [1] if prime, and an empty stack if composite.
Interpreter
Explanation
1g            # is the input > 1?
  {           # if so, continue. else, print the stack and exit
   ?          # push the user input
    (         # -1
     !        # factorial
      )       # +1
       ?      # push the input again
        /     # divide all values on the stack by the input
         x    # push if the number is an integer or not (0 or 1)
          <   # swap the top two values on the stack
           {  # is the top of the stack truthy? if so, continue, else exit
            ; # discard the top of the stack

Thunno 2, 1 byte
P

Attenpt This Online!

Attempt This Online!

minigolf, 29 bytes
iT+:,:ns,:n*;s,_;*i=+0=s0=0=*

Attempt This Online!
Explanation
Generate a multiplication table of (input-1)x(input-1):

iT+                input - 1
:                  duplicate
,                  map in [1..i-1]:
  :                  duplicate i-1 so that it's preserved across iterations of map
  ns                 swap current iteration item underneath
  ,                  map in [1..i-1]:
    :                  dup curr. iter. item of outer loop (so that it's preserved)
    n*                 multiply by curr. iter. item of this map loop
  ;                  end map
  s,_                swap up & drop our preserved curr. map value
;                  end map

Aftermath of the multiplication table:
*                  flatten
i=                 Set by equality w/ input
+                  sum that
0=                 = 0? (i.e. no items in that table that equals input)
                   Note: at this point we have i-1 underneath our top value
s                  Swap i-1 upwards
0=0=               Set all >0 values to 1
*                  Multiply (i.e. if i-1 is zero, our prime checking output is 0.)

LiveCode, 128 bytes
on mouseUp
   ask ""
   put it div 2 into i
   repeat with j=2 to it-1
      put it mod j*i into i
   end repeat
   put i>0
end mouseUp

Put in a button and press the button. Asks for a number, puts true or false reporting primality into the message box. LiveCode does support stdin and stdout, but other answers here used this method so I am as well.
A function would make more sense to me, but that doesn't seem to be the accepted method here.
Explanation
Should be pretty clear:
Starts with 0 if the input is 1, or 1 or more if input > 1.
Then for every number from 2 to the input - 1, multiplies the running total by the input modulo the number. If any of the numbers evenly divide the number, the running total will change to (and remain for the rest of the loop) zero.
At the end, report whether the running total is greater than 0. If it is, the input is prime, if it has been zero-ified at any point, the input is not prime.

GAIA, 1 byte
ṗ

Try it online!

Welcome to Code Golf, and nice answer

Tabloid, 358 293 bytes
DISCOVER HOW TO x WITH a, b WHAT IF b BEATS 1 WHAT IF ((a DIVIDED BY b) MODULO 1) BEATS 0 SHOCKING DEVELOPMENT x OF a, b MINUS 1 LIES! SHOCKING DEVELOPMENT 0 LIES! SHOCKING DEVELOPMENT 1 EXPERTS CLAIM y TO BE LATEST NEWS ON "" YOU WON'T WANT TO MISS x OF y, y MINUS 1 PLEASE LIKE AND SUBSCRIBE

Input through a JavaScript prompt(), and output 1! if the input is prime and 0! otherwise (exclamation point due to language restrictions)
-65 bytes by using BEATS (greater than) instead of SMALLER THAN (less than) and IS ACTUALLY (equal to), inverting some if conditions on the way
Readable version
DISCOVER HOW TO x WITH a, b
    WHAT IF b BEATS 1
        WHAT IF ((a DIVIDED BY b) MODULO 1) BEATS 0
            SHOCKING DEVELOPMENT x OF a, b MINUS 1
        LIES!
            SHOCKING DEVELOPMENT 0
    LIES!
        SHOCKING DEVELOPMENT 1
EXPERTS CLAIM y TO BE LATEST NEWS ON ""
YOU WON'T WANT TO MISS x OF y, y MINUS 1
PLEASE LIKE AND SUBSCRIBE

Original (358 bytes)
DISCOVER HOW TO x WITH a, b RUMOR HAS IT WHAT IF b SMALLER THAN 2 SHOCKING DEVELOPMENT 1 LIES! RUMOR HAS IT WHAT IF ((a DIVIDED BY b) MODULO 1) IS ACTUALLY 0 SHOCKING DEVELOPMENT 0 LIES! SHOCKING DEVELOPMENT x OF a, b MINUS 1 END OF STORY END OF STORY EXPERTS CLAIM y TO BE LATEST NEWS ON "" YOU WON'T WANT TO MISS x OF y, y MINUS 1 PLEASE LIKE AND SUBSCRIBE

Readable version
DISCOVER HOW TO x WITH a, b RUMOR HAS IT
    WHAT IF b SMALLER THAN 2
        SHOCKING DEVELOPMENT 1
    LIES! RUMOR HAS IT
        WHAT IF ((a DIVIDED BY b) MODULO 1) IS ACTUALLY 0
            SHOCKING DEVELOPMENT 0
        LIES!
            SHOCKING DEVELOPMENT x OF a, b MINUS 1
        END OF STORY
    END OF STORY
EXPERTS CLAIM y TO BE LATEST NEWS ON ""
YOU WON'T WANT TO MISS x OF y, y MINUS 1
PLEASE LIKE AND SUBSCRIBE

Welcome to Code Golf, and nice answer!

This language should be called “BREAKING NEWS”

ForWhile, 24 bytes
9:`[_48=';+')1;[1+;;%)=#
Takes unary number less than 99 as input, prints 0x01 if prime and 0x00 otherwise
online Interpreter
Explanation
The first half of the code is just number-parsing (ForWhile does not have a built-in for that).
The actual prime checking code is 1;[1+;;%)=.
9:`[        )            \ repeat up to 9^9 times
    _48=                 \ read one byte, check if it is equal to 48 (char code of 0)
        ';+              \ if yes, increment second value on stack
           ')            \ if no, break from loop
             1           \ push one
              ;[         \ repeat up to n (input number) times
                1+       \ increment value on stack
                  ;;%)   \ break loop if top stack value is divisor of input -> smallest divisor of number that is greater than 1
                      =  \ check if number is equal to its smallest divisor greater than 1
                       # \ print the result to standard output

binary input (36 bytes)
99[_48-:0<!:[.'2*+1]).1;[1+;;%)=48+#
prints 1 for prime and 0 for non-prime
decimal input (37 bytes)
99[_48-:0<!:[.'10*+1]).1;[1+;;%)=48+#
prints 1 for prime and 0 for non-prime

Uiua, 13 bytes
=1/+=0◿⇡.⧻&sc

Try it online! (uses a 9 byte function instead)
Couldn't find a 8-byte primality test that works for 1 yet. Correctly gives 0 (false) for the input of 0.
=1/+=0◿⇡.    input: positive integer n
      ◿⇡.    n modulo each of 0..n-1
    =0        equals 0? gives 1 for zeros and 0 for others
  /+          sum (= number of divisors minus 1)
=1            equals 1?

Now this can be 12 bytes (different SBCS link), and 8 bytes for a function, with the prime factors builtin, and parse being one character: =1⧻°/×↥1⋕&sc

MaybeLater, 52 bytes
wheni is*ifi<n{if1>n%i o=0i++}n=read()o=1i=2write(o)

Ungolfed
when (i is *){
    if (i<n){
        if (1>n%i){
            o=0
        }
        i++
    }
}
n=read()
o=1
i=2
write(o)

Naïve approach.
Try it online!

Pyth, 8 bytes
&>Q1!tPQ

Alternative that doesn't support values less than 2:
!tPQ

Perl, 35 bytes
Uses regular expressions...
$_=1x$_;s/^(11+?)\g1+$//;print$_>1

That's 34 bytes of code, plus one byte for the -n switch needed to fetch a line from stdin. Outputs 1 if the number is prime, or nothing otherwise

Stuck, 3 bytes
iv|

Prints 1 for primes and 0 for non-primes. (The definition of "truthy/falsy values" means I can't use iv, because Stuck prints False/True without knowing what those are.)

Scala, 96 bytes
#!/usr/bin/env scala
print(((a:Int)=>if(a==2)true;else!2.to(a-1).exists(a%_==0))(args(0).toInt))

JVM and yet not last place :D
Does use some bash functionality but I'm using Scala so don't be too hard on me.

It's possible in 50 bytes. :)

@EmilLundberg That code won't run. You need a main method or use the same trick I used.

Huh, you're right that it doesn't compile as scalac prime.scala. But it does run as scala prime.scala.

K, 29 bytes
(x>1)&&/x!'2_!1+_sqrt x:0$0:`

Got this off Rosetta Code, so marked it as community wiki.

XPath 2.0, 45 40 bytes
$i>1 and empty((2 to $i -1)[$i mod .=0])

For readability, incl. non-mandatory spaces (45 bytes)
$i > 1 and empty((2 to $i - 1)[$i mod . = 0])

In XPath, the only way to hand input like an integer to the processor is by passing it a parameter, in this case $i. This is hardly performant, and obvious improvement would be to use:
$i > 1 and empty((2 to math:sqrt($i) cast as xs:integer)[$i mod . = 0])

But since "shortest in any given language" and not performance was the goal, I'll leave the original in.
How it works
For people new to XPath, it works as follows:

Create a sequence up to the current number:
(2 to $i - 1)

Filter all that have a modulo zero (i.e., that divide properly)
[$i mod . = 0]

Test if the resulting sequence is empty, if it non-empty, there is a divisor
empty(...)

Also test for special-case 1:
$i > 1

The query as a whole returns the string true (2, 5, 101, 5483) or false (1, 4, 5487).
As a nice consequence, you can find all divisors (not prime divisors!) using an even shorter expression:
(2 to $i - 1)[$i mod . = 0]

will return (3, 5, 7, 15, 21, 35) for input 105.

XSLT 3.0, 209 203 201 bytes
<transform xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:x="x" version="3.0"><function name="x:p" expand-text="1"><param name="i"/>{$i>1 and empty((2 to $i -1)[$i mod .=0])}</function></transform>

Update 1: removed spaces in $i > 1, . = 0 and $i - 1.
Update 2: changed expand-text="yes" in expand-text="1", which is a new XSLT 3.0 feature
In expanded form, with the usual prefixes:
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:x="x"
    version="3.0">

    <xsl:function name="x:p" expand-text="yes">
        <xsl:param name="i"/>{
            $i > 1 and empty((2 to $i - 1)[$i mod . = 0])
    }</xsl:function>

</xsl:stylesheet>

This method uses the XSLT 3.0 feature to have a function as entry point (earlier versions did not support this). It uses the same XPath expression explained in my other post.
XSLT is notoriously verbose and starts with quite a few bytes declaring namespaces etc.
The function must be called with a typed value that derives from xs:integer. Most processor will consider that the default type if given an integer literal.

TI-BASIC, 37 bytes
Prompt N
N=1
For(A,2,√(N
Ans+not(fPart(N/A
End
not(Ans

Prompts for N and displays 1 if N is prime or 0 otherwise.
Also in TI-BASIC:

12 bytes by Thomas Kwa
24 bytes by Zenohm

I rewrote it. This would have done better as a comment as well.

Nice. I modified my answer. Incidentally, I would have commented on your post but I created this account just to contribute this and didn't have enough reputation to comment.

SWI-Prolog, 51 bytes
a(X):-X>1,\+ (Y is X-1,between(2,Y,I),0=:=X mod I).

This uses predicate between/3 which is not an ISO-Prolog predicate.

You can save 6 bytes by shifting the range of I up by 1 (thus removing the necessity for Y) and using I-1 in the mod. TIO link

You can save another 2 bytes by replacing a(X) with -X.

A bit of competition: https://codegolf.stackexchange.com/questions/57617/is-this-number-a-prime/151626#151626

JavaScript, 57
Prime finding regex.
alert(!/^1?$|^(11+?)\1+$/.test(Array(prompt()+1).join(1)))

That won't work. prompt() returns a string, not a number, so for input 3, you wind up with the string 31. The whole conversion isn't needed though. The questions allows reading the input in unary.

Yeah, I was thinking of a way to fix it. Guess I never got around to actually fixing it...

Just adding + before the prompt() should work.

Python 3, 54 bytes
A just for fun post that abuses the all function.
y=int(input());print(all(y%p for p in range(2,y))|y>1)

Explanation:
Takes all the numbers from 2 to y and calculate the mod of y and that number and return false if any of those are 0.
Edits:
Add the 1 check (+4 bytes)
Fix the check 1 logic (0 bytes)
Remove the [] (Thanks FryAmTheEggman!) (-2 bytes)
Remove the -1 from range (Thanks FryAmTheEggman!) (-2 bytes)

all can take a generator, so you don't need []. Also range(a,b) already returns [a, ..., b-1].

Cool, thanks for the tip :)

Scala, 50 bytes
val i=readInt
print(i>1&&(2 to i-1 forall(i%_>0)))

In case output to STDERR is forbidden, 65 bytes:
val i=scala.io.StdIn.readInt
print(i>1&&(2 to i-1 forall(i%_>0)))

Python 2, 45 bytes
Not the smallest entry, but I took a slightly different approach to detecting the prime numbers. Maybe it inspires someone to create an even smaller version. I couldn't discover any more savings myself.
i=a=n=input()
while i>2:i-=1;a*=n%i
print a>1

Desmos, 108 104 94 bytes
k=2
1\left\{\sum _{n=2}^k\operatorname{sign}\left(\operatorname{mod}\left(k,n\right)\right)+2=k,0\right\}

To use, enter a new line. Then, call p\left(n\rgiht). The output will be bottom right on that line.
Edit 1: Shaved {x-1} to x.
Edit 2: Changed input format to a more STDIN-esque model.

I'm not sure how Desmos works or is scored, but \left\{2=\sum _{n=1}^x\left\{0=\operatorname{mod}\left(x,n\right),0\right\},0\right\} at... possibly 101 bytes?

The link gives me timeouts. If I change the protocol to HTTP, it works. 2. The question doesn't allow submitting functions. The closest to user input I could find is putting k=1 in one field and \left\{\sum _{n=2}^k\operatorname{sign}\left(\operatorname{mod}\left(k,n\right)\right)+2=k,0\right\} in the next.

Just got a-1\prod_{n=2}^{a-1} mod(a,n), 29 bytes. Returns >0 for primes, 0 for non-primes. Note that the old solution could be golfed at least down to \left\{\sum_{n=2}^k sign(mod(k,n))+2=k,0\right\}, 48 bytes.

@EthanChapman I think you meant to place parentheses around a-1, so it would be 31 bytes. Also, it can actually be further brought down to 26 bytes: (a-1)∏_{n=3}^amod(a,n-1).

Groovy, 92 91
i=System.in.newReader().readLine()as int
print i==2||i>1&&!(true in(2..i-1).collect{i%it<1})

Such a verbose way to read from stdin...

Welcome to Programming Puzzles & Code Golf!

Ceylon, 107 112
That was my first try:
shared void p(){if(exists a=process.readLine(),exists c=parseInteger(a)){print(!(2:c-2).any((d)=>c%d<1));}}

This is a simple trial division of all numbers between 2 and c - 1, using the range operator : and the any method for iterating.
But this will also note 1 as prime. So here the corrected version:
shared void p(){if(exists a=process.readLine(),exists c=parseInteger(a)){print(1<c&&!(2:c-2).any((d)=>c%d<1));}}

That works for numbers up to 2^63-1 ... and takes quite long for larger primes (or composite numbers with large factors) – I think it took about half a minute to confirm 2147483647 (=2^31-1) as prime.
The formatted version:
shared void p() {
    if (exists a = process.readLine(),
        exists c = parseInteger(a)) {
        print(1 < c && !(2 : c - 2).any((d) => c % d < 1));
    }
}

I originally wrote the check as d.divides(c), but the modulo operator is so much shorter.
As a bonus, here is a variant for arbitrary size integers, though there is not really a point in using this due to the slowness.
import ceylon.math.whole {
    w=parseWhole,
    t=two,
    o=one
}
shared void q() {
    if (exists a = process.readLine(),
        exists c = w(a)) {
        print(c == t || !(t .. c - t).any((d) => c % d < o));
    }
}

The : range operator needs an Integer (the number of elements) as a second argument, so we use the .. operator, which takes the same type as the first argument, i.e. here a Whole, as second argument (the upper limit). 2..c-1 is the same as 2:c-2 for large c, but this becomes an empty list for two (and a non-empty list for one), so we need a different exception here than in the Integer version. It becomes mainly longer due to the imports.
The space-reduced version has length 153:
import ceylon.math.whole{w=parseWhole,t=two,o=one}shared void q(){if(exists a=process.readLine(),exists c=w(a)){print(c==t||!(t..c-o).any((d)=>c%d<o));}}

Simplex v.0.5, 23 bytes
Can probably be golfed. It's really the square root declaration that hurts. *regrets removing p (prime checking) command from syntax and sighs*
i*R1UEY{&%n?[j1=o#]R@M}
i                        ~~ takes numeric input
 *                       ~~ copies and increments pointer
  R1UEY                  ~~ takes the square root and rounds it down
       {              }  ~~ repeats until zero cell met at end
        &                ~~ read and store the value to the register
         %               ~~ takes input mod current, move pointer left
          n              ~~ logically negates current (0 -> 1, 1 -> 0)
           ?[     ]      ~~ evaluates inside if the current cell
             j1=         ~~ inserts a new cell to check for a 1 case
                o#       ~~ outputs the result and terminates program
                   R@    ~~ goes right, pulls the value from the register
                     M   ~~ decrement value

Mathematica, 48 47 bytes
<<PrimalityProving`
Echo@ProvablePrimeQ@Input[]

Saved 1 byte thanks to Martin Büttner. Echo is a new function in Mathematica 10.3. In older versions, use Print.

Groovy, 36 bytes
I found a variation of this in a course on groovy that I'm taking:
p={x->x==2||!(2..x-1).find{x%it==0}}

Test code:
println ((2..20).collect {"Is $it prime? ${p(it) ? 'Yes':'No'}"})

p={x->!(2..<x).find{x%it==0}|x==2}, saves 2 bytes.

PHP, 59 bytes
Credit goes to Geobit's answer. I basically just changed it from java to PHP.
function f($n){for($i=2;$i<$n;)$n=$n%$i++<1?:$n;echo $n>1;}

function f($n){for($i=1;++$i<$n;)$n=$n%$i?$n:0;echo$n>1;} is shorter. The language name is "Java" by the way, not "java".

AppleScript, 158 Bytes
Note that the special case for 1 adds a full 20 bytes.
set x to(display dialog""default answer"")'s text returned's words as number
repeat with i from 2 to x/2
if x mod i=0 then return 0
end
if x=1 then return 0
1
If this program ever returns 0, it won't get to the final statement, which returns 1. Therefore, truthy is 1, falsey is 0.

This might be golfed more. Might not need words. Might not need as number, because x+0 might make a number. Might not need spaces after numbers (from2, 0then, 1then). I can't check because I'm off my Mac.

Microscript II, 2 bytes
N;

Unlike the original Microscript, Microscript II provides a builtin for primality testing.

C, 59 bytes
main(_,i){scanf("%d",&_);for(i=_;_%--i;);putchar(!--i+48);}

If anything other than 1 counted as "falsey", then this would be 3 bytes smaller:
main(_,i){scanf("%d",&_);for(i=_;_%--i;);putchar(i+48);}

Please tell me if the second one is valid.

Your code gives a FP exception for input 1 on my system. 2. An integer n is falsy if the statement if(n){...} does not execute .... For C, this means that only 0 is falsy.

Mouse-2002, 22 bytes
 ?x:x.1-&FACT &SQR x.\!

Uses Wilson's theorem:
?x:                      ~ get an integer input; put it in x
   x.1-                  ~ put x-1 on the stack
       &FACT             ~ factorial it and push
             &SQR        ~ square it and push
                  x.\!   ~ modulo (x-1)!^2 % x; print

The version that doesn't use a variable is eight bytes longer, but this is because Mouse's stack operations have four- and five-byte long names. :(

JavaScript function golf, 16 13 bytes
p(pr(iai()));

function golf has just got a primality test function, that you can try online in the console on the language page! The primality test function took me 3 commits on GitHub.
Returns 1 if prime, else 0.
The variant with the alert costs us 15 bytes.
p2a(pr(iai()));

And... the first ever explanation of a function golf program!
p(pr(iai()));
p( prints
  pr( if
     iai() an integer input into a prompt
          ) is prime
           ); into the console.

So, why does this have a negative score?

@cat I assume it's because people think it's a function. The challenge calls for a complete program and this has function in the name. It looks like a full program to me though.

Factor, 56 bytes
Literally ungolfable.
USING: math.primes conv io ;
readln string>number prime?

I haven't used Factor recently, so I don't remember what must be done to print the t/f result of prime?

@kernigh print or maybe >string print? why are you asking

The task wants the result on STDOUT or something like it. This code leaves the result on the stack, and I can't remember if Factor would print the result, or if one must add more code to print the result.

Pyke, 2 bytes
_P

If the P function is given a negative number, it returns whether it's prime or not.

Pyth, 2 bytes
P_

Try it here!
Pyth now has implicit input!

Befunge 93, 33 bytes
&10p1 >1+:10g\`v
1.@.0_^#!%\g01:_

Also works by trial division, as the other befunge post, but is substantially shorter.
Interpreter here.

Unipants' Golfing Language, 53 47 bytes
i$cu^d^-l_u^^/%cu%?%d%:_?coc$d$$:__^d^-:_u?cuo:

Try it online!
(It has been implemented as a standard example in the interpreter.)

Molecule, 3 bytes
Inp

Explanation:
Inp
I   read input
 n  convert to number
  p primality test

LiveCode 8, 708 bytes
on mouseUp
    ask ""
    put p(it) into field "a"
end mouseUp
function p n
    if n is 1 then return false
    repeat with i=2 to n-1
        if n mod i is  0 then return false
    end repeat
    return true
end p

This code can be placed inside any button. It will print true or false to a field named a. It should work for small-ish integers, but will probably freeze/crash on anything too large. Byte count is size of saved LiveCode stack with one button and one field and with this code in the button.

Fith, 30 bytes
*math* load line >int prime? .

This language isn't great for golfing...
This uses the prime? function in the *math* library. Here's a version using only builtins, which is pretty much what the library function does:
line >int -> x 2 x range { x swap mod } map all .

Explanation:
line           \ line of input
>int           \ cast to int
-> x           \ set x to the top of the stack
2 x            \ push 2, then x
range          \ range from [2, x)
{ x swap mod } \ anonymous function which calculates x mod its argument
map            \ map that function onto the generated range
all            \ return 1 if everything in the list is Boolean true, else 0
.              \ print the top of the stack

You may be able to tell that this language is just a little bit inspired by Forth. It also takes cues from PostScript, Python, and functional programming.

C, 54 bytes
i;main(j){for(scanf("%d",&i);i%++j;);putchar(49^j<i);}

Must be run without parameters, so j is initialized to 1.
Reads from standard input.
Prints 1 for primes, 0 for composites (no newline).
Could save 2 bytes with unprintable output - I'm not sure if \x00 and \x01 qualify as falsy/truthy.

'\0' and '\1' are truthy and falsy according to our definition, so printing NUL or SOH should be fine.

for a less esoteric output format than printing \0 or \1, you could return i==j and save 4 bytes in the process

brainfuck, 208 202 bytes
This is the code I wrote for my Sesos answer. See that answer for a detailed explanation.
This code assumes input fits in a single cell. Attempting to take input from an empty file must set the cell to zero. It works on an unbounded tape with no wrapping, including one that can go negative. It works for all positive numbers. Output will be a byte with a value of 0 or 1.
[->+>+<<]++>[-<->]+<[>-<,]>[->+<]>[[->>>+<<<]>>>[->>>+<<<<<<+>>>]>>>-]<<<<<<+[<<<<<<]>>>>>>[-<+>]++[<[->>>+<<<]>>>[->>>+<<<<<<+>>>]>>>>][[->-[>+>>]>[+[-<+>]>+>>]<<<<<]<<<<<<]>>>>>>>>[>]>[<+>,]+<[>-<-]>.

Nim, 70 56 bytes
import os,math
let x=1.paramStr.len
echo fac(x-1)^2mod x

Uses Wilson's theorem; that is, x is prime if (x - 1)!² mod x is 1.
Takes input in unary (any character) via the first command-line argument. Outputs 1 if the input is prime, and 0 otherwise. To test:
$ nim c prime.nim
$ ./prime 11111111
0
$ ./prime 1111111
1
$ ./prime 1
0

Note that according to the Nim os docs, this solution will not work on POSIX as paramStr isn't available for some reason.

RPN, 16 bytes
lambda x isprime

This define a function checking the primality of it's argument.
Call like this:
<number> lambda x isprime eval

PHP, 70 65 bytes
for($i=2;$i<$n=$argv[1];$i++)if(is_int($n/$i)?1:0){echo 0;break;}

Empty output if the number is prime, print 0 if the number is not prime.
Not very original or best answer, but this is it...
Test online

Ruby, 33 bytes
A little longer than other solutions, but doesn't require flags:
require'prime';p$*[0].to_i.prime?
Can be run putting in a file, say prime.rb:
ruby prime.rb 97
Or directly on the command line:
ruby -e "require'prime';p$*[0].to_i.prime?" 97

Logy, 82 bytes
f[X]->X<2&1|X*f[X-1];p[&1]->0<0;p[X]->f[X-1]%X==X-1;main[A]->print[p[atoi[A(1)]]];

I have no idea what I am doing.
Use Wilson's theorem.
Ungolfed code:
factorial[X] -> X < 2 & 1 | X*factorial[X - 1];
prime[&1] -> FALSE;
prime[X] -> factorial[X - 1]%X == X - 1;
main[Args] -> print[prime[atoi[Args(1)]]];

Racket 75 bytes
(let p((c 2))(cond[(> c(sqrt n))#t][(= 0(modulo n c))#f][else(p(+ 1 c))]))

Ungolfed:
(define (f n)                 ; COMMENTS:
  (let loop ((c 2))
    (cond
      [(> c (sqrt n)) #t]     ; if no divisor found till sq root of number, it must be a prime
      [(= 0 (modulo n c)) #f] ; if divisor found, it is not a prime
      [else (loop (add1 c))]  ; try with next number
      )))

Following version is longer but more efficient for checking larger numbers since it keeps & uses previously found prime numbers:
(λ(N)(define(p n(o'(2))(c 2))(cond[(> c n)o][(ormap(λ(x)(= 0(modulo c x)))o)
(p n o(+ 1 c))][else(p n(cons c o)(+ 1 c))]))(= N(car(p N))))

Ungolfed version:
(p=subfunction to build prime number list till n; o= list of prime numbers found; c=current number being checked)
(define f
  (λ (N)
    (define (p n (o '(2)) (c 2))
      (cond
        [(> c n) o]
        [(ormap (lambda(x) (= 0 (modulo c x))) o)
                (p n o (add1 c)) ]
        [else (p n (cons c o) (add1 c))]))
    (= N (first (p N)))))

Testing:
(f 109)
(f 10)
(f 11)
(f 12)
(f 13)
(f 49)
(f 43)
(f 57)
(f 47)

Output:
#t
#f
#t
#f
#t
#f
#t
#f
#t

If I understand correctly, the solution given is a snippet, not a full program, because it inputs from the variable n.

Unary, 165192711826249169871716905363504385377479408598339493836 bytes
Well, basically 165192711826249169871716905363504385377479408598339493836 zeros.
Here is a Java program that prints the actual program:
public class Main{
  public static void main(String[]args){
    for(BigInteger i = new BigInteger("165192711826249169871716905363504385377479408598339493836"),BigInteger j = BigInteger.ZERO;j.compareTo(i)!=0;j = j.add(BigInteger.ONE)){
      System.out.println("0");
    }
  }
}

This a port of this Brainfuck answer.

PHP, 43 39 54 44 43 bytes
improved my answer from stackoverflow:
for($i=$n=$argv[1];--$i&&$n%$i;);echo$i==1;

Run with -r. prints 1 if argument is prime, empty string else.
loops $i down from $n-1 until it finds a divisor of $n; $n is prime if that divisor is 1.
6 bytes extra for the 1 case. almost happy.

Batch, 121 bytes
set i=2
if %1%==2 exit /b
if %1%==1 echo 0
:b
set /a a=%1%%%i%
set /a i=%i%+1
if %i%==%1% exit /b
if %a%==0 echo 0
goto b

Outputs 0 if it's no prime. This works only for inputs input > 0.

Dip, 1 byte
P

Pretty self-explanatory...

memes, 2 bytes
I decided to hop on the language train.
Code:
}"

Explanation:
} //Takes next input.
" //Returns `True` or `False`, representing if the input is prime.

QBIC, 21 20 3 bytes (nc)
Since the purpose of the challenge is to build a catalog, I feel it's important to keep the QBIC post up-to-date with the current state of the language:
?µ:

Explanation:
?    PRINT
 µ   QBIC's prime test, returns -1 for primes, 0 otherwise
  :  Read a number from the command line, insert that here
     The function is closed automatically because of EOF.

Previously, at 20 bytes:
:[a|~a%b|\p=p+1}?p<3

Simple trial divider. Every time b (the loop counter) cleanly divides a (our prime-candidate), p is increased. Primes will end with p at 2 (or p=1 for a=1). This then prints -1 for primes, and 0 for non-primes, which are QBasic default values for true and false resp.

Original entry, 21 bytes. This prints 1 for primes, and 0 for others. This feels more 'natural' to me than QBasic's default -1/0. Also, this only does slightly less than a/2 divisions for primes (and quits when it detects a non-prime), instead of doing a divisions regardlessly.
:[2,a/2|~a%b=0|_Xp}?q

Explanation:
:       Get the input number, 'a'
[2,a/2| FOR(b=2, b<=(a/2), b++)
~a%b=0  IF a MOD b == 0     --> Clean division == no prime
|_Xp    THEN exit program, printing 'p' (which never gets set and is 0 by default)
}       Close all language constructs: IF/END IF, FOR/NEXT
?q      We've made it through the FOR loop without division, N is prime.
        In QBIC, 'q' is auto-initialised to 1, '?' prints it.

Maverick, 25 bytes
(1:(<>@-1)//$*)%<>@=<>@-1

Try it online!
This is a pretty fun language IMO. Infix and esoteric.
(1:(<>@-1)//$*)%<>@=<>@-1
 1:                         range from 1 to
   (<>@                     first command line arg (<> called with no args)
       -1)                  minus 1
          //$*              folded over multiplication
(             )%            modulus
                <>@         the input
                   =        does the above equal
                    <>@-1   the input minus 1? If so, yields prime

SmileBASIC, Forty Four 43 bytes
INPUT N
FOR D=1TO N
P=P+!(N MOD D)NEXT?P==2

Just checks if the number has exactly 2 divisors.

You could test if P<3 it's one byte shorter and it covers the 1 cornercase.

Valyrio, 14 bytes
s∫main [ipo]

Outputs 1 if the input is prime. Otherwise outputs 0.
Explanation
s∫ tells the interpreter to enter stack mode
main [ starts the main code block
i takes an input and evaluates it
p pushes 1 or 0 to the stack depending on primality
o outputs the top item on the stack
] ends the main code block

√ å ı ¥ ® Ï Ø ¿ , 3 bytes
Ipo

p is the primality test.

NO!, 34 bytes
This was taken from the NO! GitHub page. It isn't mine
NOOOOOOO?NOOOOOOOOOOO
NOOOOOOOO?no

This should be marked as community wiki if you didn't write it.

Ruby 16+15 bytes
require 'prime';p->e{e.prime?}

Add++, 14 17 bytes
D,f,@,P
+?
$f,x
O

Try it online!
10 bytes are boilerplate for the full program requirement.
Function, 7 bytes
D,f,@,P

Fairly basic, just defines a function that performs a primality test
Built-in, 1 byte
P

As functions and main code use both different memory models and different commands, this only works in function mode and so would be invalid.

cQuents, 3 bytes
?pz

Try it online!
Explanation
?     Mode ? (query)
 p    Builtin: next prime after parameter
  z   Previous item in sequence
   )  Implicit closing parenthesis

Query mode returns true if the input is in the sequence, and false if it is not.

Note current version uses Z instead of z

Implicit, 30 29 21 bytes
<2è;:(-1>1?{;|_ñè};).

Try it online!
Whew, another 10 bugs uncovered during the writing of this program. This uses trial division.
While SimpleStack uses a ... stack, I'm going to call two stack values variables. The input will be variable i and the trial-division loop counter will be variable m. Note I might've messed up this explanation somewhere along the road of golfing.
<2è;:(-1>1?{;|_ñè};).
                       implicit input i
<2                     push i < 2
  è                    exit without implicit output if truthy
   ;                   pop i < 2
    :                   set m to input
     (.............)    do
      -1                 decrement m
        >1               push m > 1
          ?{.....}       if true
            ;             pop m > 1
             |            duplicate stack (stack: i, m -> i, m, i, m)
              _           push i % m
               ñ          compute logical NOT on i % m (truthy if i % m falsy)
                è         exit without implicit output if truthy
                  ;      pop top of stack (NOT(i % m) or m > 1)
                   )    while m > 0
                    .   increment

If the input is 0 or 1, it will print nothing, so the output will be falsy. If the input is not prime, the second è exits without implicit output (making hte output empty and therefore falsy). If the input is prime, it will reach the end of the program, and the top of stack will always be 0. . increments it, turning it to 1 (truthy). Implicit output.

Pyth, 3 2 bytes
I can't see a simpler way of doing this. My ignorance continues to amaze me.
P_

Explanation (if it needs one):
P   Prime function: factorization if positive, isPrime if negative
 _  Negate the implicit input

Test suite

No need to subtract from zero, as _ performs negation.

@Dennis I tried that earlier, it didn't seem to work...

TI-BASIC (nspire), 15 bytes
f(n):=isPrime(n

Uses the CAS isPrime() builtin.
The environment by default adds an extra parenthesis on the end of the input, making it f(n):=isPrime(n) when the function is defined in the interpreter.

I'm assuming nspire doesn't allow unclosed parentheses?

Yeah, it autocloses them.

I don't think that the TI-Nspire runs TI-BASIC. I was under the impression that it used a variant of Lua...

It also uses a form of lua for code in documents, but it does use basic for on-calculator programming (without an interpreter page)

If it autocloses them, then isPrime(n should work.

Added changes and explanation.

Python 3, 57 bytes
k=int(input());print(all(k%j for j in range(2,k))and k>1)

I think it's pretty self-explanatory.

@JonathanFrech No.

@JonathanFrech The author of this problem asked for a full program.

Common Lisp, 64 bytes
(print(=(loop as x from 1 to(setq n(read))count(=(rem n x)0))2))

Try it online!
57 bytes in Common Lisp REPL:
(=(loop as x from 1 to(setq n(read))count(=(rem n x)0))2)

><>, 46 Bytes
i> :1\/ln;
~\?:-/^?(2l~
%$}:{<;n0/?
l1- ?/1n;\

Takes input as an ascii character, prints 1 for primes, 0 for non-primes, including 1. Loops forever if input is 0 or negative.
How it works:
 > :1\
 \?:-/

Fills the stack with integers between 0 and input, inclusive.
      /ln;
~    /^?(2l~

Removes the top two values on the stack, 0 and 1. Tests if the length of the stack is <2; if it is, the value is either 1 or 2. In either case, its truthy/falsy value is the length of the stack; print it. If the length is greater than 2, it continues to the next loop.
%$}:{<;n0/?
l1- ?/1n;\

Duplicates the value being tested from the bottom of the stack. Test if it's divisible by the value at the top. If it is, print 0. Otherwise, check that the stack length is not 1. If it is, the value being tested is prime; print 1.
Edit:
Added on to this program a bit, as a part in my attempt to conquer as much of project euler as possible in ><>.
This is for Project Euler 7: Calculating the 10001st prime
a:::***31[\>?!/l1-?\]r1-:?!/r:nao1+70.
\/{*::+1<0<\%$}:{  <~~
 \:}(?!\/-1l  \         ;nr\
\!?:-1:<\ ?!\~^.38
            \] 1+70.

Comes in at 130 Bytes, although I didn't try very hard to golf it.
Pushes 10000 to the stack (since we start at 3), makes a new stack, runs the primality test on the number, starting at 3. If it's prime, decrement the counter and increase the value being tested. If its not prime, just increment the value.
The go-fish interpreter was a life saver for this--it ran orders of magnitude faster than fish.py.

Funky, 39 bytes
n=>{o=1for(i=2;i<n;i++)o=o&0<n%i o&n>1}

Try it online!

Julia, 15 7 bytes
isprime

knocked down 8 bytes thanks to caird coinheringaahing

Can you just submit isprime as a function submission?

i suppose so? good point

This doesn't work in julia 0.6+, (isprime was deprecated in 0.5 and moved to the Primes.jl package).
I guess retitle this as Julia 0.5?

The challenge spec requires a full program. Also, isprime uses a probabilistic primality test and is thus cannot be used for this challenge.

AnyDice, 68 bytes
function: p A {loop N over {2..A/2}{if A/N*N=A {result:0}}result: 1}

I was wondering if AnyDice counted as a language for PCG.se purposes,
and it turns out it does,
This is trial division, making use of the fact that AnyDice only supports integer (truncating) division.
usage:
TryIt
output [p 333332]

outputs 0(100%)
output [p 333331]

outputs 1(100%)

Whispers v2, 27 bytes
>>> ⊤ℙ
> Input
>> 1∘2

Try it online!
Whispers v1, 27 bytes
> Input
>> 1’
>> Output 2

Try it online!
Uses the builtin prime tester. Alternatively, instead of using a builtin, the following code uses Wilson's Theorem and weighs in at 54 bytes
> Input
> 1
> 2
>> 1-2
>> 4!
>> 5*3
>> 6%1
>> Output 7

Try it online!

SNOBOL4 (CSNOBOL4), 105 bytes
	N =INPUT
	X =1
	GT(N,1)	:F(C)
I	X =X + 1
	OUTPUT =EQ(X,N) 1	:S(END)
C	OUTPUT =EQ(REMDR(N,X)) 0	:F(I)
END

Try it online!
I thought about putting my explanation in all caps, but that would just look silly.
This is the brute force approach: Test if N==1, and output 0 on success, then increment X. If we reach a point where X==N, then we have found a prime number and we output 1 and terminate. If we reach a point where N %% X == 0, then we output 0.
I am still learning to golf in SNOBOL, so I think it should be possible to make this shorter.

Broccoli, 107 bytes
(fn p ($a) (:= $d 0) (for $i in (range 2 $a) (if (= $a (* $i (int (/ $a $i)))) (:= $d (+ $d 1)))) (= $d 1))

With whitespace added:
(fn p ($a)
    (:= $d 0)
    (for $i in (range 2 $a)
        (if (= $a (* $i (int (/ $a $i))))
            (:= $d (+ $d 1))
        )
    )
    (= $d 1)
)
(map p (range 1 20))

This language is a bit of a pain to work with:

You can't take input.

You can't define a function from within a function.

You can't pass a lambda to a map or reduce or a filter.

There is no modulo function.

I'm sure this could be shorter somehow, but I'm just not seeing it.

095, 35 bytes
1Xid1.=(DD,,{d_.%(yX]D}dYs]D1.=[1s]

Returns 0 for composite and 1 for prime.
Explanation:
1X                                  ~ Set True to X
  id                                ~ Take input and duplicate
    1.=                             ~ Check if equal to 2
       (DD                          ~ If not, delete last two items
          ,,                        ~ Subtract 2
            {                       ~ For that many times,
             d_.%                   ~ see if iterator divides into input
                 (yX]               ~ If it does, set False to X
                     D}             ~ Delete last item, close loop
                       dYs]         ~ Duplicate input, print X
                           D1.=[1s] ~ If input = 2, say True

Triangularity, 7 bytes
.).
IEp

Try it online!
Triangularity, 49 bytes
Much more interesting solution, without using built-ins for divisors / prime test. Outputs 1 if the input integer is a prime, 0 otherwise.
....)....
...If)...
..rF@)I..
.f/Df={L.
)2=......

Try it online!
How it works?
Removing the characters that make up for the triangular padding, here's what the program does:
)If)rF@)If/Df={L)2= || Full program. ToS = Top of the Stack
)I                  || Get the 0th input.
  f                 || And cast it to an integer.
   )r               || Create the integer range [0 ... ToS - 1).
     F        {     || Filter the elements of this list which satisfy this function:
      @)If/Df=      || Runs each (X) on a separate stack, keeps those that yield 1.
      @             || Increment X.
       )If/         || And divide the input by it.
           D        || Duplicate, push two copies of the ToS.
            f=      || Floor the second copy and compare it with the first one.
               L    || Length.
                2=  || Check if it equals 2. Implicitly output the result.

Forth (gforth), 73 61 57 bytes
: f { n } 0 n 1 > if 1 n 2 ?do n i mod 0> * loop then . ;

Try it online!
Stack-Only variant, 76 68 64 61 bytes
: f 0 over 1 > if 1+ over 2 ?do over i mod 0> * loop then . ;

Try it online!
Explanation
0 over             \ place a 0 on the stack then place a copy of the input on top
1 >                \ check if the top of the stack is greater than 1
if                 \ if true execute the if, otherwise skip it
   1+              \ add 1 to our tracking variable (so replace 0 with 1)
   over 2          \ place n and 2 on the top of the stack,
   ?do             \ loop from 2 to n, skip loop if n = 2
      over i mod   \ get the modulo of n and the loop index (so n % i)
      0>           \ check if modulo is greater than 0 (not divisible)
      *            \ multiply bool (-1 or 0) by the top of the stack (shorter version of and)
   loop            \ end the loop
then               \ end the if statement
.                  \ output the top of the stack

17, 102
17 is a language I made a few days ago and am now trying out some challenges with.
A single ascii character is taken as input and 0 is returned for false, its lowest factor for true.
0{1 # 2 # 1 + : 2 @
% 0 == 2 * 2 # 1 # == 3 * + 0 @ }2{2 # $$ 0 @}5{0 $$ 0 @}777{0 0 @ I 1 @ 1 2 @}

Expanded:
0 {
  1 # 2 # 1 + : 2 @
  % 0 == 2 * 2 # 1 # == 3 * + 0 @
}
2 {
  2 # $$ 0 @
}
5 {
  0 $$ 0 @
}
777 {
  0 0 @ I 1 @ 1 2 @
}

17 starts at block 777 and runs blocks depending on value stored at 0.
Block 777: Set value 0 to 0, set value 1 to ascii code of input char, set value 2 to 1.
Block 0(first run after block 777): Increase 2 by 1, if 1 mod 2 == 0, go to block 2 unless value 1 is value 2, then goto block 5
Block 2: Load 2 and print, then exit
Block 5: Print 0 and exit

Quarterstaff, 94
golfed 1!
10-?[-38a a a a a a a a a a>a10-?]a>b b[>b>d a>c c[1>c1d>d b d(.>e|>d1>e)c]e f>f1b]2-f(.|1)48!

Try it online!
How it works:
Quarterstaff has a register i call "value", and multiple other registers i call variables, which are referenced by name.
value starts as 0
10 add 10 to value
- multiply value by -1 (value now -10) (this is because it checks for the end of the integer by checking for newline, which has a charcode of 10)
? add an inputted characters charcode to the value (which will be 48 for "0", for example)

the first loop:
[ begin while loop. these work like brainf***'s while loops, but instead of a cell, it uses the value.
- multiply value by -1
38 add 38 to value
At this point, the program has 0 if the most recently input character was "0", -1 if it was "1", -2 if it was "2" etc.
a a a a a a a a a a this is a reference to the variable a 10 times. this means we add 10*a to the value. a starts of as zero
>a store this value in a. this means we have just done the following: a=10*a-int(inputted_char). a is always a negative number when using digits. when the loop is done, a will hold the inputted number *-1. this also happens to set the value to 0. assignment with > always sets the value to 0
10-? this is the same code as we executed before entering the loop. this means that we will input a new character, but if we got to the end of the number, we exit the loop.
] loop end. if the value is zero, we exit, otherwise returning to the start. this while loop executes until it has taken all the input into the variable a in negation (22 becomes -22)

a now holds the negative of the inputted number. why is it negative? well, because it's shorter. if we want to decrease the magnitude by 1, we only have to add 1, not use -, add 1, then use - again.
a>b the a adds a to the value (which is now exactly a because it was previously 0), and >b puts this value into b. in effect b=a, because the > sets the value back to 0. remember a and b are negative
b there is a space in between variable names, because otherwise they get parsed as one name. this just makes the value b, because the value was 0 before

another while loop
[ begin the loop
>b this puts the value inside b, and value now = 0. at the first execution of the loop, this has no effect apart from value = 0, but at subsequent executions, it will be adding 1 to b, which will decrease it in magnitude until reaches -1. we use b to represent divisors
>d value will always be 0 when executing this. this will set d to 0. this is necessary because it is set to other values later in the loop
a>c means c=a. remember a is negative, and so is c
c value += c (value =c because value was 0). c is negative,
[ nested while loop. tests for the value of c in first and subsequent executions because the value is set to c just before it checks. This loop performs modulus
1>c because we have c in the value, this means add 1 to c. remember c is never >0. this makes c a counter down to 0
1d>d add 1 to d (value was 0 before these commands). d is a non-negative integer
b d value += b + d. because b is negative and d is positive, this means that the value will now equal 0 iff abs(b)=abs(d).
(.>e|>d1>e) this is an if else expression/command thing. because it immediately follows the b d which is 0 iff the absolute values of b and d are equal, it means it will execute the else iff abs(b)=abs(d), otherwise the then part. so, the part that executes if the value isn't 0 is .>e. . sets the value to zero, >e puts that 0 in e. e is 0 by default. if b and d have equal magnitude though, >d1>e executes. this puts 0 in d (because the value was zero if we're executing this part) and then 1 in e. if this is the last execution of the loop, it means that we will exit the loop with 1 in e, which represents being divisible. otherwise we haven't finished the modulo process yet. if we executed the if not 0 part and this was the last execution, we exit with 0 in e, representing not divisible.
c value = c (because value was 0 before)
] close nested loop.
back to the not modulus part
e f>f value =0 prior to execution, and f += e (f = e + f)
1b this sets the value to b+1 (remember b is negative). this will get stored in b next execution of the loop, if there is one.
] close outer loop

tying up
2-f value (which equals 0) += f-2. prime numbers exited the modulus loop with e=1 precisely 2 times.
(.|1)48 if that isn't 0, set value to 0, but if it is 0, set to 1. then add 48, to the value, which is either 1 or 0.
! print character with the corresponding  char code. thus, print "1" (49) for primes and "0" (48) for not primes

You can save a byte by moving the >e out of the if expression: Try it online!

Pyt, 1 byte
ṗ

Try it online!
Implicit input
ṗ   primality test
Implicit output

K, 23 bytes
x=&/(y*/:y:!x)?'x:0$0:`

yay for algorithmic improvements!
Explanation
No operator precedence kind of acts against us here, so we have to resort to paranthesis
x:0$0:`

reads the input and saves the result to the variable x
y:!x takes the list 0..(x-1) and saves it to the variable x
y*/:y applies * using /:, so every element in y is multiplied by y, creating a matrix
?'x searches every column of the matrix for x, returning the length if x is not found
x=&/ &/ takes the minimum of the list by folding it with the min operator, and then checks if it is equal to x. If not, there should exist a combination of two numbers smaller than x result in x, i.e it is not a prime

Befunge-93, 28 bytes
&:0\1\1>-#1:__\#0:#*_$:*\%.@

Try it online!
Uses Wilson theorem, i.e. that ((n-1)!^2)%n returns 1 if n is prime else 0.
How It Works:
&:0\1\ Get input n and dupe it, putting a 0 and a 1 in-between
      1>-#1:_ Decrement and dupe until the number is empty
             _\#0:#*_$ Multiply until you reach the zero, yielding (n-1)!
                      :* Square it
                        \% Mod this value by the original value
                          .@ Print the mod and terminate

><>, 23 22 bytes
:1vn%$*:~<
@*>$1-:?!^:

Try it online!
Uses Wilson's theorem again, i.e. (n-1)!**2 %n returns 1 if n is prime, 0 if it is not. Takes input via the -v flag.
How it Works:
:1v Dupe the value and push a 1 as the total
  >$1-  Decrement the copy
      :?!^  If the copy is 0 go up to the first line
@*>       : Else Multiply the total by the copy and repeat the decrement
If we went up to the first line
        ~< Pop the excess 0
      *:   Square the total
  vn%$     Print the total modulo the original value and exit with an error

Forked, 57 54 bytes
$P11>p1+"Us'v
    |       |
1%& :-msU"p-:-
    |
  &%<

The dual-fork loop is really beautiful. Try it online! Alternate versions with identical bytecount:

Try it online! - less redundant code
Try it online! - less redundant code and some cool wrapping behavior

Short explanation
This uses a trial division method, equivalent to this C code:
int isPrime(int n) {
    for (int i = 2; i < n; i++)
        if (n % i == 0)
            return 0;
    return 1;
}

Long, thorough explanation
Before we begin, let us define two values:

n: the inputted number, to be tested for primality
i: the loop counter for the trial division method

Here's the program's control flow:
---->-------v
    |       |
--- :-------:-
    |
  --<

The forks : compose one big loop. The rightmost fork exits the loop and prints 1 if n-i is zero, i.e. if n mod i is always positive, meaning n has no divisors other than 1 and itself.
The leftmost fork exits the loop and prints 0 if n mod i is zero, meaning n has a divisor other than 1 and itself.
The initial four bytes set up the stack. Let's say the input n is 11.
CODE  STACK    EXPLANATION
$     [n=11]   read integer input n
 P    []       pop n, stash in register
  1   [i=1]    push i (initially 1)
   1  [i=1, 1] push filler value for later popping

The code p1+"Us' between the redirects > and v pushes n-i.
CODE    STACK        EXPLANATION
p       [i=1]        pop top of stack (useless value or result of n%i)
 1+     [i=2]        add 1 to top of stack
   "    [i=2, 2]     duplicate top of stack
    U   [i=2, 2, 11] copy register onto stack
     s  [i=2, 11, 2] swap top two stack values
      ' [i=2, 9]     subtract top two stack values

Then the IP turns South and forks. If n-i is zero, it turns East and immediately wraps around to hit 1%& (push 1, print, exit), therefore returning a truthy value if If there are still values of i to check, the IP turns West, hitting the code that computes n mod i:
CODE  STACK        EXPLANATION
p     [i=2]        pop n-i
 "    [i=2, 2]     duplicate top of stack
  U   [i=2, 2, 11] copy register to stack
   s  [i=2, 11, 2] swap top two stack values
    m [i=2, 1]     compute n mod i

The IP is forked, turning South and returning 0 if n mod i is 0. Otherwise it turns North and immediately turns East, where i is incremented and the whole loop is done again.

Forth, 82 65 bytes
: f 1 ?do i' i mod 0= + loop 0= ;
1 tib dup 9 accept evaluate f .

Ungolfed:
: f                        \ def f(counter, n):
  1 ?do                    \     for i in range(1, n):
    i' i mod 0= +          \         counter -= n % i == 0  # In Forth True == -1
  loop
  0=                       \     return counter == 0
;
1                          \ counter = 1
tib dup 9 accept evaluate  \ n = int(input()) # Forth version inputs 9 digits at most
f .                        \ print(f(counter, n))

It has at least one downside though: Forth echoes back what it accepted, because it is strongly terminal and/or REPL oriented, so feeding it 7 yields 7 -1
Run it!

Python 3, 42 55 bytes
n=int(input());print(sum(n%m<1 for m in range(1,n))==1)

Try it online!
The n%m<1 comparison is sufficient to check that n is a multiple of m.  I start the range at 1 to correctly handle the case n == 1.

Go, 231 bytes
package main
import."fmt"
type c chan int
func main(){a,k:=0,make(c);Scan(&a);go func(d c){for i:=2;;i++{d<-i}}(k)
for{p:=<-k;if a==p||a<p{Print(a==p);break};j:=make(c)
go func(i,o c,p int){for{j:=<-i;if j%p!=0{o<-j}}}(k,j,p);k=j}}

This solution contains a sieve that generates primes, when the primes exceed the candidate, or there is a match it outputs true for primes and false for non-primes.
The main code is blatantly stolen from this playground example.
Since it is rather silly I probably wont be golfing this solution any further
Try it online!

Python 2, 51 bytes
p=input()
print all(p%i for i in range(2,p-1))==1<p

Try it online!

Procedural Footnote Language, 41 bytes
[1]
[PFL1.0]
[1] [PRIME:[INPUT]]
[PFLEND]

Explanation
This program is fairly straight-forward: The body of the document (above the [PFL1.0] tag) is the result/output, and is equivalent to the evaluated contents of footnote [1]. Footnote [1] evaluates to the result of the [PRIME] function on input from STDIN.

Reality, 1 byte
P

This takes input via stdinput and return true if it is a prime and false other wise

Alternate :
If taking input is not allowed then
p number

space is not required (replace number with your number)

Note : Reality is an under-development language and was created after this challenge

Racket, 67 42 bytes
(require math/number-theory)(prime?(read))

When run in DrRacket, this will prompt the user for an integer and return #f (false) if the number is not a prime and #t (true) if the number is a prime.
Previous (and much more complicated) version:
((λ(l)(or(= l 1)(ormap(λ(x)(=(modulo l x)0))(range 2 l))))(read))

Z80Golf, 30 bytes
00000000: 040c 0934 0c28 0d0a b720 f960 6909 38f4  ...4.(... .`i.8.
00000010: 2534 18f9 24cd 0380 6f7e cd00 8076       %4..$...o~...v

Try it online!
Takes a single-byte input. Outputs a zero byte for prime byte values, and some non-zero byte for composite values. (This value is actually the number of distinct prime divisors!)
Disassembly:
  inc b
  inc c
  add hl, bc  ; HL = BC = $0101.
              ; We use $0100~$ffff as a prime sieve array.
  inc (hl)    ; Mark 1 as composite.

next:
  inc c       ; Loop for C from 2 to 255.
  jr z, done
  ld a, (bc)
  or a
  jr nz, next ; If *BC is marked as composite, skip.

  ; sieve
  ld h, b     ; Mark *(BC), *(2*BC-256), *(3*BC-512) ... as composite.
              ; (So for BC = $0103, this is $0103 $0106 $0109 ...)
  ld l, c
clear:
  add hl, bc
  jr c, next  ; Run until HL overflows! This is more work than necessary, but shorter.
  dec h
  inc (hl)
  jr clear

done:          ; Now H = 0.
  inc h        ; Now H = 1.
  call $8003
  ld l, a      ; Now HL = $0100 + input.
  ld a, (hl)
  call $8000   ; putchar(*HL)
  halt

Elixir, 122 bytes
o=fn f,p,1->1
f,1,c->0
f,p,c->case rem(p,c)do
0->0
_->f.(f,p,c-1)end end
{i,_}=Integer.parse IO.gets""
IO.puts o.(o,i,i-1)

Try it online!
Can definitely be golfed. Outputs 1 for prime and 0 for composite

This breaks on 1. Otherwise, replacing True by 0<1 and False by 1<0 shortens it a bit.

1 has been fixed, and I just switched True / False out for the easier int equivalents

Scala, 40 bytes
def f(n:Int)= !(2 to n-1).exists(n%_==0)

Try it online!

Unfortunately, this challenge doesn't allow functions.

Foam, 9 bytes
;# #.% .#

Foam isn't on TIO yet, but it should be coming soon!
Outputs 1 for prime and 0 for nonprime.
Foam has a prime checking builtin.
;#   <- read number
#.%  <- is number prime?
.#   <- output number

Flobnar, 25 bytes
%\ @
:&|\<
-:1>
1*<
>>  *

Try it online!
Outputs 1 for prime, 0 for composite. Uses the -d flag to get numerical input. Be aware that the time it takes for each number doubles, where an input of 18 will take ~6 seconds, and 19 takes ~12 seconds. This is because the algorithm (based on Wilson's theorum) looks somewhat like:
def f(n):
    if n == 0:
        return 1
    else:
        return n*f(n-1)*f(n-1)
print f(input)*f(input)%input

So basically the function takes 2n+1 steps, doubling the time it takes for each step. If you want to test the code itself, you can use this (+2 bytes) which is merely 2n steps. It basically removes the surplus extra call of f(n-1) in the return of the function.

Elixir, 75 72 bytes
n=String.to_integer IO.gets""
IO.puts Enum.all?2..n-1,&rem(n,&1)>0||2==n

Try it online!

Pixiedust, 59 bytes
Takes input in the ++ register, and leaves output in the .. register.
*.+*.*+.
+.
.++*++
+*..
**+..+++*
*+++*+*.*+
+**
+..
.*...*

Explanation
* . +* .*+.       Set the +* register to 2 - this is the factor being checked
+.                Define a label whose name is the empty string
. + +* ++         Test whether +* has reached ++ yet
+* . .            If it has, go to the "." label
* *+ .. ++ +*     Set the branch register to ++ modulo +*
* ++ +* +* .*+    Increment the factor
+* *              If the branch register is not 0 (meaning it's not a factor) restart the loop
+. .              The "." label
. * .. .*         Invert the .. register

Cardinal, 24 21 bytes
Thanks to @Jo King for golfing off 3 bytes
Code:
%
:
=>-!.
v#~M!@
-
R^

Try it online!
Explanation:
%      //Start program
:      //Read input
=      //Copy input to inactive value
v#     //Loop around and pass copy of pointer up and to right after each loop
-      //Decrement active value by 1
R^     //End program if input=1

*>-!.     //If active value =1 print 0 (occurs just before line below ends program)
*#~M!@    //If inactive value divisible by active value end program
**
**

F#, 79 84 bytes
Fixed as per Dennis's suggestion.
stdin.ReadLine()|>int|>fun n->not(Seq.exists(fun i->n%i=0)[2..n-1]||n=1)|>printf"%b"

Now works for input = 1.
Can be run same as before.

Original submission:
I didn't see an F# answer so...
stdin.ReadLine()|>int|>fun n->not(Seq.exists(fun i->n%i=0)[2..n-1])|>printf"%b"

Can be compiled with fsc or run directly in fsi. Takes a newline-terminated string from stdin and spits out a bool to stdout when run.

Unfortunately, that doesn't work for input 1. Try it online!

Remember, lambdas are allowed, so... 44?

C#, 116 bytes
Non fancy full program entry (cherry-picking some stuff from java):
class P{static void Main(string[] a){int i=2,n=int.Parse(a[0]);for(;i<n;)n=n%i++<1?0:n;System.Console.Write(n>1);}}

Ink, 68 51 bytes
-(l)
+(n)[+]
->l
*(r)[{n}]
{n%(r+1)%n:->r|{n==(r+1)}}

Ink was made for writing interactive fiction. It was never meant to be a general-purpose programming language. So it only has one way to recieve input.
Choice prompts.
So the way it works is, if option 2 is labelled with the number you want to check, you pick option 2. Otherwise you pick option 1 to increment option 2's label. So, if you want to check if 15 is prime, you'd input
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
2

TIO doesn't handle this, unfortunately.
-17 bytes by using read counts of named options instead of creating variables. This brings the overhead of taking input this way down to something like 24 characters (or even 18 if we don't care about minimising the text from the prompts), compared to the 10 for defining a parametrised stitch and returning from it.
Since full programs can use global variables and read counts, but stitches that have to be reusable can't, using full programs might actually pay off in places where I thought it wouldn't. Neat.

C++ (gcc), 85 bytes
#include<iostream>
int main(){int n,d=1;for(std::cin>>n;n%++d%n;);std::cout<<(n==d);}

Try it online!

-2 bytes thanks to @ceilingcat

Ungolfed
#include <iostream>
int main() {
    int n,d=1;
    for (std::cin >> n; n % ++d      // Trial division. If n dividible by d, end.
                          % n        /* No effect when n > 1.
                                        But required to make sure the loop ever ends if n == 1
                                     */
                            );
        ) { /* Empty loop body */ }  /* d is now the lowest number greater than 1 which
                                        divides n (or 2 if n == 1)
                                     */
    std::cout << (n==d);             // If that number is n, n must be prime.

}

Port of my Ink answer. Competitive in multiple other languages. I wasn't going to post this, but I couldn't find a C++ compiler that would compile the existing C++ answer.

T-SQL, 116 bytes
WITH t AS(SELECT 2n UNION ALL SELECT n+1FROM t WHERE n<5e4)
SELECT*FROM z,t WHERE p%n=0AND n<p OPTION(MAXRECURSION 0)

There is an Oracle SQL answer here, but couldn't find a Microsoft T-SQL version for this classic question.
Notes:

Line break is for readability only.
Returns no rows if prime, returns 1 or more rows otherwise. This is allowed per this output rule.
Input is taken via pre-existing table \$z\$ with INT field \$p\$, per this input rule.
Handles values of \$p\$ up to the max value of the INT type, \$2^{31}-1\$

Explanation:
Generates an in-memory number table \$t\$ from 2 to 50k (which exceeds the square root of the max int), then joins to the input table \$z\$ and uses the modulo operator % to test for divisibility. Any values that divide evenly are returned, so an empty result means the input is prime.
OPTION(MAXRECURSION 0) is needed to recursively generate a table with more than 100 rows, unless you've altered this configuration setting on your SQL server.
Optimized for bytes, not speed; checks more values than is strictly necessary.

Keg, 43 36 6 4 bytes (SBCS)
@MPƒ

-2 bytes using a BFL function
乁( ⏒ ͜ʖ ⏒ )ㄏ
Answer History
6 bytes
:;¡²$%

Try it online!
-30 bytes thanks to @JoKing
No TIO as it needs to be updated due to a bug found with the ² operator.
Transpiles to:
from KegLib import *
from Stackd import Stack
stack = Stack()
printed = False
duplicate(stack)
decrement(stack)
factorial(stack)
square(stack)
swap(stack)
maths(stack, '%')

if not printed:
    printing = ""
    for item in stack:
        if type(item) is Stack:
            printing += str(item)

        elif type(item) is str:
            printing += custom_format(item)
        elif type(item) == Coherse.char:
            printing += item.v

        elif item < 10 or item > 256:
            printing += str(item)
        else:
            printing += chr(item)
    print(printing, end="")

36 bytes (SBCS)
 ¿®n21®t{:©n≠©t0≠*|:©n$%[1|0]®t1+}©t.

Try it online!
-7 bytes by not using a variable to keep track of the count.
Explained
¿®n21®t{:©n≠©t0≠*|:©n$%[1|0]®t1+}©t.
¿®n                                 #Take the number to check and store it in variable n
   2                                #This will act as the divisor counter
    1®t                             #This will act as the return value, indicating the primality
       {:©n≠©t0≠*|                  #While the counter isn't equal to n and there isn't a divisor yet
                  :©n$%             #Take the counter and number, then swap for modulus
                       [1|0]®t      #Depending upon the result set t to 1 if it doesn't divide otherwise 0
                              1+}   #Increment the counter
                                 ©t.#Print the result

43 bytes (SBCS)
¿®n2®c1®t{©c©n≠©t0≠*|©n©c%[1|0]®t©n1+®c}©t.

It's a real ugly mess, but it works. I'll explain it all later.
Also, doesn't work on TIO due to a bug that I found. It should work soon however.
Use the latest github interpreter

Wren, 48 43 bytes
I feel surprised that I think better when using W instead of Wren. Also, the 1-primalty problem is fixed.
Fn.new{|i|(1..i).where{|x|i%x==0}.count==2}

Try it online!

W d, 5 bytes
(Possibly the only <=5-byter that does not use a prime or number factorization built-in?) (The two spaces here represent a tab)
àTéBΦ

repr'd:'‡T\tB⑸'
Unpacked:
m!Wk2=

Explanation
This is really difficult to read, so an explanation will be nice.
    W    % (implicit) Foreach the inclusive range from 1 to the input:
bam      % The "bam" magic! Just kidding. Evaluates b % a
         % Since b is out-of-bounds, this takes the upper-level input
         % as the operand.
   !     % Remove those that aren't valid multiples.
     k   % Is the length of the array ...
      2= % ... equal to 2?
         % i.e. primes have exactly 2 factors: 1 and itself

Crax! That sounds like a good golfing language name.

Looks like there is a bug in the interpreter and I had to change the compression...

Symbolic Raku, 17 bytes
$_=?($_%%[^] ^$_)

Try it online!
Suprisingly, this is shorter than the my previous Raku answer, though one byte longer than using the built-in
Explanation:
$_=                # Set the output to
   ?(           )  # The boolean of
     $_            # If the input is
       %%          # Divisible by
         [^]       # Only one of
             ^$_   # The range from 0 to input-1

cQuents, 3 bytes
?pZ

Try it online!
Explanation
Usually, I'd put the commands here, but I feel like that wouldn't be enough.
? outputs if the input is in the sequence.
Item 1: Z returns 0, as Z returns the previous item, and Item 0 is always 0. p finds the next prime number (2).
Item 2: Z returns 2. p finds the next prime number, which I thought would be 2, but no, it returns 3.

Haskell + Parsec, 181 bytes, no math
import Text.Parsec
a=anyChar
g s=a>>= \c->try(many1$string$c:s)*>eof<|>g(c:s)
main=readLn>>= \x->print$0<case parse(try(a*>eof)<|>(pure<$>a>>=g))""$replicate x '0'of{Left _->1;_->0}

Try it online!
Ungolfed and explanation:
import Data.Either (isLeft)
import Text.Parsec (eof, (<|>), try, anyChar, many1, string, parse)
import Text.Parsec.String (Parser)

-- Successfully parses any string of nonprime length, and fails on all others.
-- Exactly one character is not prime. If more than one character exists, we recurse with `go`.
notPrime :: Parser ()
notPrime = try (anyChar *> eof) <|> (pure <$> anyChar >>= go)
    -- `go cs` reads a character `c` and determines whether the remaining input is `c:cs` repeated.
    -- If so, the parse succeeds. If not, we call `go (c:cs)` to read another character and test again.
    where go :: String -> Parser ()
          go cs = do
                  c <- anyChar
                  try (many1 $ string $ c:cs) *> eof <|> go (c:cs)

-- Checks whether the parser `notPrime` fails on a uniform string of the specified length
isPrime :: Int -> Bool
isPrime n = isLeft $ parse notPrime "" (replicate n '\0')

Try it online!

qalc/Qalculate, 8 bytes
If reading from any variable is allowed:
p-1)!²%p

Otherwise 12 bytes:
ans−1)!²%ans

The great thing about "programming" in a calculator is that you can basically just enter formulas directly.
Example usage in Bash for the "ans" case:
echo "5" | qalc -t -f - "ans−1)! ²%ans"

Note that I added a space after the exclamation mark only because Bash otherwise tries to interpret "!²" as an "event". It's not actually required by qalc, which can be seen by for example creating this file:
5
(ans−1)!²%ans

…and then executing it with qalc -t -f test.txt.
Other consoles or other ways of calling qalc than Bash might not have this problem.
The calculation can also be entered in "interactive mode" by simply running qalc -t, entering the number and then entering the expression on the next input. This also works in the GUI program "Qalculate".
Meta explanation:
The output is 0 for non-prime numbers and a positive integer for prime numbers. I let this run in a loop for all numbers up to 10000 and it was always 1 for prime numbers, but I haven't checked whether that is guaranteed yet.
This solution is based on this Labyrinth answer. I essentially just found something (qalc) that has all the parts of the formula as builtins instead of having to program all the parts myself on a lower level.
The -t argument hides the interpreted calculation, so that the output of the example command looks like this:
5
1

…instead of like this:
5 = 5
rem(factorial(ans - 1)^2, ans) = 1

Reading the number in in qalc is difficult. It has a system of variables, but I haven't figured out how to set those in the CLI yet. In the GUI it's pretty easy. That's one of the main reasons why I also provided a solution with "ans".
Inserting the number into the formula two times would mean modifying the "program", which is surely not allowed.
There seems to be no way to execute multiple expressions non-interactively with qalc, except by reading in a file. In this case, I used - as a "file", which is StdIn, and used that only to store the input in ans, which is implicitly done by qalc. You could also use an actual file and use the number in that file as input. Or you could even say that ans is already the input of the "program", in which case the program is simply the 12 bytes seen above, or even any variable, then the 8 byte solution.
Algorithm explanation:
The Wikipedia article linked in the Labyrinth answer looks pretty confusing, but the principle is easy:
(6-1)!²%6 = 1·1·2·2·3·3·4·4·5·5%6
          = 1·1· 6 · 6 ·4·4·5·5%6
          = 6 ·   something    %6
          = 0

This works because every non-prime number is the product of at least two factors that are smaller than that number. Prime numbers aren't, which leads to something like this:
(5-1)!²%5 = 1·1·2·2·3·3·4·4%5
          = 1·1·2·2·3·3·4·4%5
(no multiplication of those factors results in anything divisible by 5)
          = 1

The squaring is necessary in case there is only one prime factor and that occurs twice:
(9-1)!²%9 = 1·1·2·2·3·3·4·4·5·5·6·6·7·7·8·8%9
          = 1·1·2·2· 9 ·4·4·5·5·6·6·7·7·8·8%9
          = 9 ·         something          %9
          = 0

I originally wrote this answer for TI-Basic:
fPart((Ans-1)!²/Ans

That's just 10 bytes, but it fails on the input 13 already, due to floating point imprecisions in those large numbers (12!²=229442532802560000). So the only difference to an even/odd checker within the working range is 9 and it does not fulfil the criterion to work up to 255. For inputs above 42 it even crashed from an overflow (42!²>10¹⁰⁰).

Java (JDK), 105 bytes
interface P{static void main(String[]a){long i=2,n=new Long(a[0]);while(n%i++>0);System.out.print(i>n);}}

Try it online!

Pxem, Content: 0 bytes + Filename: 54 bytes.

Filename (escaped): ._.c\002.y.d.a.c\002\003.t.x.c.m.%\001.y.d.a.c.m\001.+.c.t.c.!\001.-.a.n
Content is empty.

Usage

Input is given from stdin, as a string of decimal integer.
Outputs the input number for truthy; no output for falsey.

How it works
._XX.z
# let input be n
# get out if <2
.a.c\002.y.d.aXX.z
# let i be 2
# while i*i<=n (or i*i-1<n); do
.a.c\002\003.t.xXX.z
  # if n%i<1; then exit; fi
  .a.c.m.%\001.y.d.aXX.z
  # i++
  .a.c.m\001.+.c.t.c.!\001.-XX.z
# done; print n
.a.a.n

Try it online!

PPL 1.0.5, 85 bytes
fnp(n){
declareb=1
declaref=4<5
loop n - 2{
b=b+1
ifn%b<1{
f=3<2
}
}
unsetb
returnf
}

It is a "good practice" (defined by me, of course) to unset all unneeded variables before returning. The unset statement is like delete in JavaScript. The fn statement defines a function and returns the flag. Still many bugs to iron out (remember, this is still being developed) but seeing as this is a catalogue of primality tests, thought I might post one. You have to unset n and f each time you recall the function, though.

Duocentehexaquinquagesimal, 23 bytes
7 ÇÇW∞DćƒΣZ;ndž“~3¦€`н¸k

Try it online!

SmallBasic, 163 bytes
n=TextWindow.ReadNumber()
t=1
If n<2 Then
t=0
Goto e
EndIf
For i=2 to Math.Power(n,.5)
If Math.Remainder(n,i)=0 Then
t=0
Goto e
EndIf
EndFor
e:
TextWindow.Write(t)

This is so self-explanatory. But some key points:-

A simple algorithm, Set the prime check value to 1, iterate through 2 to square root of input. If there are any divisors set prime check value to 0, else continue. At last output it.

What a shame, its Square root builtin is shorter than power by 1/2.

MMIX, 14 bytes (56 instrs)
(jxd)
00000000: 31ff0001 7a00ff00 31ff0002 6300ff03  1”¡¢z¡”¡1”¡£c¡”¤
00000010: e3010002 f7010000 1e020001 feff0006  ẉ¢¡£ẋ¢¡¡œ£¡¢“”¡©
00000020: 7a00ff00 32ff0201 e7010001 59fffffb  z¡”¡2”£¢ḃ¢¡¢Y””»
00000030: 7b000001 f8010000                    {¡¡¢ẏ¢¡¡

Disassembled:
prime   CMP  $255,$0,1
        ZSNZ $0,$255,$0     // if(n == 1) n = 0
        CMP  $255,$0,2
        CSZ  $0,$255,3      // if(n == 2) n = 3
        SETL $1,2           // i = 2
        PUT  rD,0
0H      DIVU $2,$0,$1       // loop: q = n / i
        GET  $255,rR        // r = n % i
        ZSNZ $0,$255,$0     // if(!r) n = 0
        CMPU $255,$2,$1
        INCL $1,1
        PBNN $255,0B        // if(q >= i++) goto loop
        ZSNZ $0,$0,1
        POP  1,0            // return (bool)n

Knight, 35 bytes
;=y;=x+0P1;W&=z>x=y+1y%x y 0O&-xT!z

Try it online!
Edit: Outgolfed by sampersand
Rough.
Prints true for primes, false or 0 for non-primes.
# prompt for a number, coerce to integer
; = x + 0 PROMPT
# loop counter
; = i 1
# Loop while x > y and x % y != 0
; WHILE & (= cmp > x y) (% x y)
    : NOP
# Output result. The - x 1 returns false for 1.
: OUTPUT & (- x 1) (!cmp)

ErrLess, 47 bytes
q@1=1-[{3+}2xY@;>1-[{@;%0=1-[{0#.};1+xy}2]y1_#.

Could probably get golfed a lot more...
Prints 0 if the input is not prime, -1 if it is, no trailing newline.
It uses -1 as a truthy value, since that is used for if-constructs, and what you get if a comparison is true.
Explanation
q           { Input a number: (p) }
@1= 1-[{    { If p == 1 }
 3+         { 1 -> 4, so that it correctly identifies 1 as non-prime }
}
2x          { Push a stack containing the number, and two: ((p 2)) }
Y @;> 1-[{  { While p > i }
 @;%0= 1-[{ { If p%i == 0 }
  0#.       { Print 0 and halt }
 }
 ;1+x       { Increment i: ((p i++)) }
y}2]y

1_#.        { Print -1 (ErrLess's truthy value) and halt }

ErrLess is a stack-based language I made for fun over the last few months. You can read the docs here, and I also started a tutorial.
Try it online!

MathGolf, 1 byte
¶

   -- for each line in input
¶  -- 1 if it's prime or 0 if not (works with lists too)
   -- implicit print

Try it online!

Excel, 34 bytes
=SUM((MOD(A1,SEQUENCE(A1))=0)*1)=2

Link to Spreadsheet
Limited to \$n <= 2^{20}\$ because of SEQUENCE().  A 40-byte alternative that works for \$n<(2^{20}+1)^2\$ is below.
=SUM((MOD(A2,SEQUENCE(SQRT(A2)))=0)*1)=1

I think that =AND(MOD(A1,SEQUENCE(A1-2,,2))>0) should work for 33 bytes - basically, invert the logic and search only the range from 0...n-1 for divisors

I like the idea but SEQUENCE(A1-2,,2) breaks for A1 < 3.

Oh that's a good catch there - in that case the only improvement I can think of is pretty boring - -SUM(-(MOD(A1,SEQUENCE(A1))<1))=2 for 33 bytes

Vyxal, 1 byte
æ

Try it Online!

Vyxal, 7 bytes
‹¡›$%¬

No shady built-ins, just pure, beautiful maths.
Basically Wilson's theorem
\$\large{(n-1)!+1 } \equiv 0 \left(\mod n\right)\$
Try it Online!
Explanation:
‹¡›$%¬
‹¡       push n-1 factorial
  ›      push n+1
   $%    modulo top two items swapped
     ¬   apply logical not

Python3, 53 bytes
(lambda n:all(n%i for i in range(2,n)))(int(input()))

Thunno, 1 byte
(Technically it's \$1 \log_{256}(96) \approx\$ 0.82 bytes, but that doesn't show up on the leaderboard)
N

Attempt This Online!

Python, 73 Bytes
import math
y=lambda b:b>1and math.factorial(b-1)%b==b-1
print(y(input()))

-37 from The Thonnu :O
+20 to fulfil challenge requirements
-6 by using math.factorial.
This code is based on Wilson's Theorem.

59 by using an anonymous function

@TheThonnu The rules say it needs to be a full program, so this 59 byte version is invalid. But it can be 82 bytes by using an anonymous function in that full program: Try it online!, and 75 bytes in Python 2, because its input() is the same as Python 3+'s eval(input()): Try it online! And incidentally, your 59 byter is not a true anonymous function, but it can be in Python 3.8+: Try it online!

Also, just in case you didn't know about it, there is a way to search for other Python answers to this question.

@Deadcode I did, in fact, search through all the Python answers to see how it compared with the others. Also, thanks for telling me about the full program thing, it's really annoying that old challenges have that requirement.

60 bytes

@TheThonnu this is python in general, this only works for python 2.

Yours also only works in Python 2 since you aren't converting the input() to int. But anyway, 66 bytes, works in Python 2 and Python 3.

hyperscript, 82 69 65 bytes
def f(n)set x to n-1 repeat while n mod x decrement(x)end log x<2

This is shorter than a recursive solution because hyperscript doesn’t have a great way to do optional parameters.

n: <input type="number"style="font-size:1.5rem;width:4.5ch"_="on change call f(my value)" />

Ungolfed:
def f(n)
  set x to n - 1
  repeat while n mod x
    decrement(x)
  end
  return x is 1
end

Scratch, 81 bytes

Try it on Scratch!
Scratchblocks syntax:
define(n
set[i v]to((n)-(1
repeat until<(0)=((n)mod(i
change[i v]by(-1
say<(i)=(1

This works best if the procedure is checked as "Run without screen refresh." If the option is unchecked it will still work, but will take n frames to output the correct result (i.e. the result will be incorrect for n frames).

C (gcc), 119 71 69 bytes
p;main(a){for(scanf("%d",&p);++a<p;)p=p/a*a-p?p:1;puts(p-1?"1":"0");}

Thanks to ceilingcat for the reduction to 71 bytes.

Thanks to ceilingcat for another 2 bytes shaved off by using puts instead of printf.

Outputs 0 (falsy) when it's composite and 1 (truthy) when it's prime.
My first C answer. To me, it's just a mix of Python and Assembly. Well, at least it's probably not as long as Java...
printf("Try it online!")

Putting headings that don’t provide semantic purpose is i usually not great for accessibility tools like screen-readers, but it’s probably not that big a deal here

Vyxal 3.0.0-beta.2, 8 bytes
1?R%0C1=

Try it online! (link is to literate version)
alternatively
1 input a->b mod 0 count 1 equal?

The fun of pre-releases
Explained
1?R%0C1=
1?R       # Range [1, input)
   %      # input % each in ^
    0C    # Count the number of 0s. This will return 0 for input = 1, because range [1, 1) is []
      1=  # Does that equal 1?

Created with the help of Luminespire.

Why not just use the built-in? Has it not been implemented yet?

@TheEmptyStringPhotographer that's right. It hasn't been implemented yet

JavaScript (Node.js), 30 bytes
f=(n,i=n)=>i==2||n%--i&&f(n,i)

Attempt This Online!
2 bytes longer than this solution but uses a slightly different method so I thought I'd post it.
Returns falsey (0 or NaN) for composite, true for prime.
Pretty simple - checks n % i for all i from n down to 2, returning 1 only if 2 is reached.

Uiua, 19 bytes
=2/+⌕0◿+1⇡.parse&sc

If this was just a function, it'd be 10 bytes. But it's a full program so the parse function is needed :sob:
Thanks Dennis very cool.
Explained
=0/+¬±◿↘2⇡.parse&sc
          .parse&sc  # Read the input as a number (which I wouldn't need if this was a function submission)
       ↘2⇡.          # Range [2, input)
      ◿              # input % n for each n in ^
    ¬±               # And invert the sign. Honestly this could just be `=0`, but where's the fun in that.
  /+                 # Summate that
=0                   # Does the sum equal 0?

Created with the help of Luminespire.

Cabsi, 108 bytes
1PUSH 1,""
2INPUT
3DUP
4DEC
5DUP
6ROT
7DUP
8ROT
9MOD
10JNP 90
11POP
12SWAP
13GOTO 4
90POP
91POP
92EQ
93PRINT

Try it
Cabsi is Conor O’Brien’s new stack-based BASIC derivative. It has 2 stacks, but this solution only uses one of them. This is a full program, taking an integer from STDIN and outputting a zero or a one.
Explanation:
1   PUSH 1,"" REM. Stack [1 ""]
2   INPUT     REM. Stack [1 N]            Print the string, push an int from STDIN
3   DUP       REM. Stack [1 N N]

4   DEC       REM. Stack [1 N D]          D is the denominator, decremented every iteration, starts at N-1
5   DUP       REM. Stack [1 N D D]
6   ROT       REM. Stack [1 D D N]
7   DUP       REM. Stack [1 D D N N]
8   ROT       REM. Stack [1 D N D N]
9   MOD       REM. Stack [1 D N (N % D)]
10  JNP 90    REM. Stack doesn’t change.  If the result of the modulo was 0, jump to 90
11  POP       REM. Stack [1 N-1 N]
12  SWAP      REM. Stack [1 N N-1]
13  GOTO 4    REM. Stack doesn’t change.  Jump to line 4

90  POP       REM. Stack [1 D N]          At this point, N was divisible by D
91  POP       REM. Stack [1 D]
92  EQ        REM. Stack [(D == 1)]       If the denominator is 1, then N is prime, otherwise it’s composite
93  PRINT     REM. Write to STDOUT

Mathcad 15, 15 bytes
valid in both Mathcad 15 and Mathcad Prime 3.1
not valid in Mathcad Prime Express (no symbolics)
n:=103   IsPrime(n)->

where -> is the symbolic evaluation operator
although
IsPrime(103)->

would be shorter still
edit 103 to taste
In response to the question from @Dennis the following might be helpful
Mathcad is, from a user perspective, a whiteboard in which you directly type in your expressions, programs, plots, etc and obtain the results either directly in the worksheet or export them (in some instances (eg, Excel) you can embed a "component" directly in the worksheet and access the application through the component. It also allows you mix text and expressions across the page(s) as well as down, making it almost a literate programming system.
In the above example, the input and output are all on the worksheet.  All you need to do to change the 103 is click on it, delete the digits and add your own. If auto calculation is on, then Mathcad updates the output from the IsPrime function, otherwise choose the manual calculate option (which is simply pressing F9 in the case of Mathcad 15).  Simples.
There are also file read and write functions if you want to do it the hard way, but Mathcad's interface makes it completely unnecessary for such a simple task.
See this link https://www.ptcusercommunity.com/message/420452#420452 for an example of an over-the-top means of finding the middle value of a vector (list).  What you see is what I typed in or what Mathcad computed in response.  If I were to edit the worksheet to, say, change v1's value from seq(6)+11 to seq(9)+20, Mathcad would almost instantly change the output from the "augment" expression to show the new value of v1 together with its corresponding indices.  I'd have to manually rearrange the v2 expressions to make room for the new v1 but that's as simple as dragging the mouse around the affected expressions, which selects them, and then dragging the expressions to the new location.   Easy.  Even I can do it!

Is there no way of obtaining user input in Mathcad?

That depends upon what you mean by "obtaining user input".  I've added a bit more text to my original post to help clarify how a typical Mathcad might change the number to be tested - just edit it directly on the Mathcad "worksheet" and Mathcad will update the result.

Please make sure you add in the byte count to the title of your post so that it can register on the leader board. Check the question on how to format it.

Do you which algorithm is used by IsPrime? Are you sure it's not a probabilistic one like Miller-Rabin?

STATA, 62 bytes
di _r(a)
gl c=$a-1
forv b=2/$c{
if!mod($a,`b') gl c=0
}
di $c

Ungolfed
display _request(number)
global maxtest = $number-1
forvalues counter=2/$maxtest{
    if !mod($number,`counter') global $maxtest = 0
}
display $maxtest

This tests every integer from 2 to number-1 for divisibility. By printing number-1 as the output, it prints a 0 for an input of 1. Today I learned that STATA has truthy/falsey values. Previously I assumed I could only use (in)equalities in conditions. Note: this does not yet work in the online interpreter and is only valid in the proprietary STATA interpreter.

Mathematica, 33 bytes or 61 bytes
Two answers are provided:
Manipulate[PrimeQ[n],{n,1,255,1}]

<<PrimalityProving`
Manipulate[ProvablePrimeQ[n],{n,1,255,1}]

As explained in the implementation documentation, PrimeQ[] is known to produce correct output for arguments less than 10^16 (though is widely believed, on heuristic arguments, to be correct for any input).  (User Charles claims this bound can be increased to 2^64 ~= 10^19 in an answer here.)  It tests for small primes, uses Miller-Rabin with bases 2 and 3, then uses a Lucas test.  ProvablyPrimeQ[] uses a much slower testing procedure, Atkin-Morain (reference with further citations), but is known to be correct and can produce a certificate of primality or witness of compositeness, if desired.  So, PrimeQ[] meets the challenge (255 is much less than 10^16), but ProvablyPrimeQ[] meets the specification "primality test" without reservation.
These wrap the PrimeQ[] call into a widget for user interaction.  See the docs for a visual example.  This widget provides a slider over the range 1 to 255 with unit increments.  Next to the slider is a button to provide additional controls: a textbox for direct input and "playback" controls.  It's interesting (at most, three times  :-)  ) to watch this widget iterate through the range.

The rule for hardcoding are "If (and only if) your language is unable to accept any kind of user input" (emphasis mine). Mathematica can take user input, so I believe it needs to use that (see this answer for an example).

@Sp3000 :   Huh.  Did not know about Input[].  So, ..., is the local protocol to withdraw the whole solution, or keep the documentation that the solution you cite (and many others here) do not provably test for primality?

@Sp3000 : I now also perceive a bit of a gap between the rule you reference and the other rule "If your language is able to read from STDIN or accept command-line arguments".  I certainly can't make Mathematica do that (and I think this negative capability is why I went the way I did).  But I agree that Mathematica meets the description you have.  Yet I can imagine settings where neither clause applies.

The rule you mention was indeed badly phrased, so I've rephrased it. However, the rule Sp3000 mentioned clearly stated that hardcoding is only allowed if there are no alternatives. Since Mathematica has Input[], your three snippets are invalid in its current form.

@Dennis : The third snippet receives user input, as described.

ProvablePrimeQ doesn't work without Needs["PrimalityProving"]`.

@MartinBüttner : Right you are.  You wouldn't believe how much I've customized my init.m.  Or maybe you would (especially after this).

C++, 96 bytes
main(int c,char**a){int n=atoi(a[1]);for(c=2;c<n;c++){if(n%c==0){puts("0");return;}}puts("1");}

It the same method as the C program using trial division, it just reads the value in as command line arguement.

Yorick, 20 characters
is_prime(read(,"i"))

read(,"i") reads an integer from STDIN and is_prime is the builtin prime tester of Yorick. Outputs 1 if prime and 0 otherwise.

VBA Excel  - 53 bytes
Golfed, to run in the immediate window :
t=false:for i=2 to j-1:t=(t Or j mod i=0):next:?not t

Performs a simple check for all values from 2 to j (the input)-1. If every division has a non-0 modulo, then it returns true (prime), otherwise it returns false (non-prime or error).
If you want to test this here is a larger code snippet that provides an inputbox for j:
j=inputbox(a):t=false:for i=2 to j-1:t=(t or j mod i=0):next:?not t

And for people that need it in a sub/function (ungolfed) :
function isprime(byval j as integer)  ' sanitize input to an integer.
  t=false                             ' set default return to false.
  for i=2 to j                        ' loop starting at 2 (so 1 or less is not prime).
    t=(t or j mod i=0)                ' check if i is a divisor of j
  next                                '      and add to existing return
  isprime=not t                       ' if any i is a divisor then the return is false
end function                          '      so return the opposite (isprime)

By the rules, if you have an input method you have to incorporate it. Also, little bug, you're returning TRUE for 1. In the spirit of your approach, I suggest turning the test around (and saving a couple of bytes): j=inputbox(7):t=j>1:for i=2 to j\2:t=t and 0<j mod i:next:?t

Hassium, 140 Bytes
use Math;func main(){n=Convert.toNumber(input());b=Math.floor(Math.sqrt(n));for(i=2;i<=b;++i)if(n%i==0){println("0");exit(0);}println("1");}

Lengthy:
use Math;
func main () {
        n = Convert.toNumber(input());
        b = Math.floor(Math.sqrt(n));
        for (i = 2; i<= b; ++i)
                if (n % i == 0) {
                        println("0");
                        exit(0);
                }
        println("1");
}

Mumps, 29
R J F I=2:1:J W:I=J J Q:J#I=0

Output is nothing if not prime, repeat the number if prime. [[ Looks kind of ugly, but I did this to save a carriage return, as carriage returns aren't echoed on user input. It was also easier to see the number out again than just a 1 or zero, that was confusing on longer queries, especially if they contained a '1' at the end. ]]
Test runs:
USER>R J F I=2:1:J W:I=J J Q:J#I=0
1234312343
USER>R J F I=2:1:J W:I=J J Q:J#I=0
12345
USER>R J F I=2:1:J W:I=J J Q:J#I=0
11141111114111

In these three runs, 12343, 12345 and 1114111 are the inputs (the 'R J' reads standard input into the J variable - but the carriage return is not echoed to the output).
As 12343 is a prime, it's echoed directly after the input; as 12345 is not prime, it sits alone. 1114111 is prime, but if I output just a single '1' to indicate prime, it would be much more difficult to tell if it was or not. I leave it up as an exercise to the reader to remember what was entered for the input number. :-)
[[ I wanted to output a character like '*', but then I would have needed to enclose that in quotes thereby making the answer longer. As would adding my own carriage returns...]]

VBA, 160 bytes
For casuals only. Is MsgBox a STDOUT equivalent?
Sub p(n)
Dim t
For i = 2 To n - 1
If n / i = Int(n / i) Then t = True
Next
If t <> True Then
MsgBox n & " is truthy"
Else
MsgBox n & " is falsy"
End If
End Sub

Your code can be significantly improved to Sub p() For j=2To n+1 t=IIf(n Mod j=0Or n<2,"falsy","truthy") Exit For Next Debug.? IIf(n=2,"truthy", t) End Sub
112 bytes

Actionscript 3, 504 bytes
There are 265 bytes for the actual code. Nearly half the bytes come from the required xml file used by Adobe Debug Launcher to run the swf.
This is run by executing adl P-app.xml -- n to test n, followed by
echo %errorlevel% to see the result.
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://ns.adobe.com/air/application/18.0"><id>P</id><filename>P</filename><versionNumber>1.0</versionNumber><initialWindow><content>P.swf</content></initialWindow></application>

package{import flash.desktop.*;import flash.display.*;public class P extends Sprite{public function P(){var n=NativeApplication.nativeApplication;n.addEventListener('invoke',function(e){var p=e.arguments[0],i=2,c=p==1?0:1;while(c>0)c*=p%++i;n.exit(int(p==i));});}}}

Burlesque, 7 bytes
blsq ) 71fC
{71}
blsq ) 71fCL[1==
1
blsq ) 72fC
{2 2 2 3 3}
blsq ) 72fCL[1==
0

fC does a prime factorization. If the length of the resulting block is 1, then we have a prime. Note that this isn't as fast as a Miller-Rabin or similar obviously :p. With the next planned release this will be two bytes.

AniRad, 30 29 bytes
Probably not the shortest program:
 #
 W
 I
 P
 v
 >~1=
 ~
 0
 =

Another possible program is, 30 bytes:
#WIP>v~0=
     ~
     1
     =

Information:

# = Starting point, pointer direction is to the right
W = User input, directly adds this to the stack
I = If-statement, or is equal to
P = If the stack is prime
v = If false, assign the pointer direction to the right
> = If true, assign the pointer direction to the bottom
~ = Reset the stack
0 / 1 = Assign the stack to 0 / 1
= = Print the result of the stack

The following paths are executed in this program:

If W  = prime, path = WIP~1=
If W != prime, path = WIP~0=

This is a 2D esolang I created, which looks a bit like a magic square. This is a programming language in it's early stage, so a lot of functions aren't implemented yet. Also, a lot of bugs might occur, if you find a bug, please report it.

DStack, 66 bytes
025SSd01kKCccscS0kT0cK1kAsd34SSd1ccd0sd1ddsScsdk0cD0cS0kTcdsKkdtcK

Gogh, 1 byte
e

Run using:
$ ./gogh oi "e" <input>

The operator e pushes the primality of the TOS. Implicit input and output.

Pylongolf2, 4 bytes
cnz~

Explanations:
cnz~
c    read input
 n   convert to integer
  z  primality test (beta8+)
   ~ print it.

Racket, 31 bytes
(require math)(λ(n)(prime? n))

A standard library has a function for it. If we want to keep the import but write our own, we could do this for 51 bytes:
(require math)(λ(n)(equal?(list 1 n)(divisors n)))

On the other hand, if builtins were disallowed, for 64 55 bytes, thanks to @MatthewButterick, we can write our own:
(λ(n)(=(count(λ(i)(=(modulo n(+ i 1))0))(range n))2))

Old one, for 64:
(λ(n)(equal?'(1)(filter(λ(i)(zero?(modulo n i)))(range 1 n))))

55 bytes: (λ(n)(=(count(λ(i)(=(modulo n(+ i 1))0))(range n))2))

@MatthewButterick Nice! I'll add that.

@MatthewButterick from the docunentation, it seens like range needs two args, but I guess I was very tired when I was reading it.

Also, (λ(n)(prime? n)) is the same as prime?, so if (require math)(λ(n)(prime? n)) is an acceptable 31-byte answer, then (require math)prime? ought to be an acceptable 20-byte answer

@MatthewButterick I was very tired when I edited that in last night and I swore I read your name correctly... sorry about that :P

@MatthewButterick In fact,  I think I fell asleep immediately after clicking "Save Edits". Also, no, just importing a stdlib function isn't usually enough, it needs to have a wrapper implementation around it.

Sage, 22 bytes
lambda N:N in Primes()

Try it online

(Super old but...) Submissions have to be full programs.

UGL, 26 bytes
id?u:cuul^^/_c=?_=ocd$:_u:

Try it online!
How it works:
id?u:cuul^^/_c=?_=ocd$:_u:
id?u:                       int i = input(); if i==1: i=0;
     cuu                    int test = 2;
        l              _u:  while test != -1:
         ^^/_c=?                if i % test == 0:
                _=o                 print(i==test);
                   cd$              test = -1;

reticular, 6 bytes
in@pp;

A four-byte function:
[@p]

Explanation
in@pp;
i       take input
 n      convert to number
  @p    check for primality
    p   print
     ;  terminate

R, 19 Bytes
 ->n;sum(!n%%1:n)==2

Starts with a right assign to n. i.e. precede the code with the desired n. then it merely checks primeness of n. Prints TRUE or FALSE implicitly
If you don't like right assign as an input method then for 24 bytes you get:
sum(!(n=scan())%%1:n)==2
or
n=scan();sum(!n%%1:n)==2

Which assigns within the operator.
If you want explicit answer printing, then for 28 bytes:
 p=function(n)sum(!n%%1:n)==2

RProgN, 102 Bytes
 'i' asoc true i 1 - ] 1 > while [ 'a' asoc i a / i a // = if [ [ false else [ end a 1 - ] 1 > end [ [

Explanation
 'i' asoc           # Associate the implicit input with i
true i              # Push true to the stack, push i to the stack
1 -                 # Subtact 1 from the top of the stack
] 1 >               # Duplicate the top value of the stack, compare that it's larger than 1
while               # While the top of the stack contains a truthy value
    [               # Pop the top of the stack (The conditional in this case)
    'a' asoc        # Associate the top of the stack with a
    i a /           # Push i divided by a to the top of the stack
    i a // =        # Push i integeral divided by a to the top of the stack, compare the top and underneith the top for equality
    if              # if i/a = floor(i/a), essentially
        [ [ false   # Pop the conditional, and the 'true' we slipped in earlier, push false in in place of it
    else            #
        [           # Pop the conditional anyway
    end             #
    a 1 - ] 1 >     # Subtract 1 from a, duplicate it, and compare that it's larger than 1
end                 #
[ [                 # Pop the conditional, the value of a, which leaves only the bottom value we previously inserted, which is implicitly printed

RProgN doesn't have any method of input as of yet, as such, Any input needs to be written in pure form at the very start of the code, such that 23 'i' asoc .... An Extra byte is added to the score, because a space is required in front of any command.

Pyret, 58 bytes
i=1
(i == 1) or any({(x):num-modulo(i,x) == 0},range(2,i))

You can try this online by copying the code into the online Pyret editor!
Pyret programs are designed to be run in the online editor, so there's no way to read from STDIN. Here, the variable i represents the input. The program returns true if i is not prime and false if i is prime.

If there's no input from STDIN, maybe its best to do a function instead

@JoKing This challenge doesn't allow functions.

Yabasic, 43 bytes
Input""n
For d=2To n
p=p+!Mod(n,d)Next
?p=1

Try it online!

Pepe, 53 bytes
Uses trial-and-error modulus, so gets slower in larger integers.
REeEREErEEEEErREEeEeEReeREEEEeEeEReRererrEEreEErEeree

Try it online! Outputs 0 for truthy and none for falsy.

Spice, 93 bytes
;i;m;t;c;r@REA i;ADD 0 1 c;SUB i 1 m;ADD c 1 c;MOD i c t;SWI t 1 9;SWI c m 3;ADD 0 1 r;OUT r;

This outputs [1] for a prime, and [] for a non-prime.
Un-golfed explanation:
;i;m;t;c;r@ - Declare vars (@ marks end of declarations)
(line 0) REA i;      - Read input into i
(line 1) ADD 0 1 c;  - Set counter c = 1
(line 2) SUB i 1 m;  - Set store input-1 as m
(line 3) ADD c 1 c;  - Start of loop, c+=1
(line 4) MOD i c t;  - Store mod of  t=i%c
(line 5) SWI t 1 8;  - if t < 1 (if non-prime, leave loop) to line 8
(line 6) SWI c m 3;  - if c < m continue loop (go to line 3)
(line 7) ADD 0 1 r;  - set result as truthy value - r = 1
(line 8) OUT r;      - output result, r

tq, 10 bytes
?-1!xp*p%?

Explanation
Uses Wilson's theorem to do the prime-checking.
?-1!        # Generate all numbers from 2 to input - 1
    x,      # Preserve this value, prevent it from being printed
      p*p   # Generate all possible combinations of those numbers
         %? # Does the product of any combination equal to the input?

C# (Visual C# Interactive Compiler), 62 bytes
int n=int.Parse(ReadLine()),i=2;while(n%i>0&i++<n);Write(n<i);

Try it online!

LCGFuck inputNumeric=true, 138 bytes
(Will turn this into a GitHub repository soon)
1 1im1-1
1 1om2-1
1 1om1 1
<{>>>o+1 1m0<<om
<}>>1-1om0>+om
<<<++1 1 1 32
1 4 12 69 4
1 1 7 78 2
{>>>+++++c+c+++++c+++<<c<{+}}>>>c++c<c+c+c

Try it online through this TIO JS interpreter
A brainfuck variant invented by me but uses a list of linear congruential generators (LCGs) instead of cells.
The \$N=1\$ case took too much more bytes to deal with.
Ungolfed and Explanation
1 1 im 1 -1                    # Storage for the input, since the input can only be retrieved once
1 1 om 2 -1                    # Used to prevent wrapping. Necessary for handling N = 1 case
1 1 om 1 1                     # Counts up from 2 to N
<{                             # While N % counter == 0 (If N == 1 the loop is skipped)
 >>>o+                         #  Gets and increments the counter value
 1 1 m 0 <<om                  #  Use a new LCG to check N % counter
<}                             # Loop
>>
1 -1 om 0 >+om                 # The output of this LCG will be 2 if N is prime
<<<++                          # Move two states forward (2 - 2 = 0 if prime)
1 1 1 32                       # LCG for space
1 4 12 69 4                    # LCG for E, I, M
1 1 7 78 2                     # LCG for N, O, P, R, T
{>>>+++++c+c+++++c+++<<c<{+}}  # Output "NOT " if this LCG is not at state 0
>>>c++c<c+c+c                  # Output "PRIME"

Technical Details
(Copied from my obsolete challenge proposal on an LCGFuck interpreter)
An LCG is defined with 5 numbers, like 12345 678 90 -123 45. The last two numbers are optional and default to 0.
LCGFuck has 3 storage variables, the LCG list, the number list and the number memory. The functions are as follows:

LCG list: Cyclic list that stores all LCGs created. Every entry is in turn a list of 5 numbers in the order [a, b, c, d, e] as notated in the introduction. It has a pointer that controls which LCG is chosen at the moment, and moves in a cycle through the list.
Number list: Ordinary list that stores the numbers for LCG definition. It can store at most 5 numbers.
Number memory: A single variable that can be read and written with an input or an LCG output.

LCGFuck has 14 operators, namely:

\n (newline): Creates an LCG with the numbers in the order of [a, b, c(, d(, e))] and clears the list if the number list contains 3 or more numbers. No-op if the number list contains no more than 2 numbers.
<: Shifts to the previous LCG circularly (back to the last when moving from the first).
>: Shifts to the next LCG circularly (back to the first when moving from the last).
+: Moves the current LCG to the next state (calculates x' = (a * x + b) mod c)
c: Prints the output of the current LCG as a character (with the output as the codepoint).
n: Prints the output of the current LCG as a number (with a trailing space)
o: Writes the output of the current LCG to number memory
i: Reads a value from the input and writes it to number memory. There is two input mode, one reading a character one time (inputNumeric=false), and one reading a number one time (inputNumeric=true)
s: Reads the value from number memory and seeds the current LCG with it
m: Reads the value from number memory and pushes it to the number list
[]: Output loop. Executes the loop if the current LCG is non-zero
{}: State loop. Executes the loop if the state of the current LCG is non-zero

An integer, optionally with a negative sign at the front, pushes the number to the number list. Any characters other than the newline \n and any of -0123456789[]{}<>+cimnos are no-ops.
The code runs linearly from the first characters, except when loop ends are encountered. Loops can be nested but must be paired accordingly from the innermost loop to the outermost loop.

Help, WarDoq!, 1 byte
p

Outputs 1 if the input is prime (positive or negative, differs from the other solution), 0 otherwise.

Add++ -i, 9 bytes
L,dFSbL2=

Try it online!
Using my favourite approach without any actual primality built-ins
Explained
L,dFSbL2=
L,          # A lambda called by the -i flag that:
  dF        # pushes all the factors of the input and the input
    S       # uniquify the stack - this is so that `1` is handled correctly
     bL2=   # does the length of the TOS equal 2?

flax, 1 byte
V

What can I say here?

Fig, \$3\log_{256}(96)\approx\$ 2.469 bytes
{Lk

Try it online!
Outputs with reversed boolean - 0 for truthy, any other integer for falsy.
Fig, \$2\log_{256}(96)\approx\$ 1.646 bytes
mp

Try it online!
Builtin solution.

APL(Dyalog Unicode), 9 bytes SBCS
2=0+.=⍳|⊢

Try it on APLgolf!
A tacit function which takes a number and returns a boolean.
Explanation
2=0+.=⍳|⊢
  0+.=    the count of the number of 0s in
       |  the remainder from
        ⊢ the argument
          (divided by)
      ⍳   the numbers from 1..n
2=        equals 2

Easyfuck, 35 31 bytes

D‘ň␗Č_-ZňÚG‰VŕPůňµ2’>Bům×É␗ţVSHY8

due to lack of unicode representations for c1 control characters, they have been replaced by their superscripted abbreviations
Decompressed:
"$>!>!>--<[$<%-`(>>+)J$>!>-]>$/~++'

"$>!>!>--<[$<%-`(>>+)J$>!>-]>$/~++'
"$>!>!                              input an 8bit integer into 1st cell and copy it into 2nd and 3rd
      >--<                          set 4th cell to 254 and go back to 3rd
          [                ]        while loop
           $<%-`(>>+)               modulo 2nd cell by 3rd and if 0 increment 4th
                     J$>!>-         copy 1st cell to 2nd and decrement 3rd
                            >$/     divide 4th cell by self to get to 0 or 1
                               ~++' turn 1 into 0 and vice versa, then print

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes